Tin Can
Tin Can

Reputation: 2870

Why does a failable init require all variables to be set?

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?

Upvotes: 1

Views: 190

Answers (2)

Luca Angeletti
Luca Angeletti

Reputation: 59526

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

Upvotes: 1

rickster
rickster

Reputation: 126157

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

Upvotes: 1

Related Questions