This is due to a change in 1.2 Now, before you return nil from a class's failable initializer, you must set all the properties to valid value. The reason being, the deinit for a class still runs even after the initializer fails, and for correct code, it needs to know that all the properties are validly initialized (also bear in mind the class may be a subclass, and the inheriting class might also rely on valid initialization of properties after its initializer fails).
Implicitly unwrapped optionals are initialized to nil by default – but only if they are declared var. If they are declared with let, then they are immutable and so can only be initialized once, so can’t start off as nil and then change later. Hence, the var version works, but the let version doesn’t.
Note, in the recent update to the Swift book, the code is slightly different – it initializes name first, then fails:
class Product {
let name: String!
init?(name: String) {
self.name = name
if name.isEmpty { return nil }
}
}
Also note, structs don’t have the requirement to initialize all their members before failing, only classes (presumably because structs don’t have the complications of deinit or inheritance).