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).