1

In a class that has a failable initializer, all the variables must be set before returning nil.

This is a near copy from the Swift Programming Language Guide:

class Product {
    let name: String // The guide has this as String! so it can compile
    init?(name: String) {
        if name.isEmpty { return nil }
        self.name = name
    }
}

The guide tells us that name needs to be String!, and true enough the above does not compile.

We're told "For classes, however, a failable initializer can trigger an initialization failure only after all stored properties introduced by that class have been set to an initial value and any initializer delegation has taken place." But the guide doesn't explain the reason value types are allowed to skip setting all the variables, while reference types must do so.

My question is why are classes required to initialize all the variables?

Tin Can
  • 2,540
  • 2
  • 29
  • 39
  • See my answer: http://stackoverflow.com/a/26497229/3068061 – mustafa Dec 11 '14 at 18:54
  • Should we close this as a duplicate of http://stackoverflow.com/questions/26495586/best-practice-to-implement-a-failable-initializer-in-swift ? – Martin R Dec 11 '14 at 19:29
  • @mstysf Yeah, this is what I was looking for. I was trying to ask what the reasoning behind the rule was. – Tin Can Dec 11 '14 at 19:48

2 Answers2

1

The key bit (emphasis added):

... only after all stored properties introduced by that class have been set to an initial value and any initializer delegation has taken place

Initialization chaining requires that each initializer in the chain complete its part of the job before delegating (whether from a convenience initializer to a designated initializer in the same class, or from a subclass to a superclass). If you delegate to another initializer before setting up the state you're responsible for, the other initializer gets a partially-initialized object, which Swift doesn't allow. (And the other initializer has no way of knowing that yours is already doomed to fail.)

Even in your case, where there's no superclass and you're not delegating within the same class, the rule still applies. (In a sense, you have an invisible superclass, and its initializer is being implicitly delegated to.)

rickster
  • 124,678
  • 26
  • 272
  • 326
  • This still seems like a deficiency in their definite assignment analysis algorithm for the degenerate case of a non delegating initializer - to require initialization code that serves no purpose. Obviously performance is not an issue for the exceptional case of failure, but it would make for cleaner code. I can only imagine that it is not an easy problem to solve though. – Chris Conover Jul 22 '15 at 21:45
1

This is now fixed on Swift 2.2

We can now use failable initializer and return nil before setting all the properties.

enter image description here

Luca Angeletti
  • 58,465
  • 13
  • 121
  • 148