snaggs snaggs - 18 days ago 5
Swift Question

Swift: why I can't call method from override init?

I have following code example (from PlayGround):

class Serializable : NSObject{
override init() { }
}

class Device : Serializable{

var uuid:String

override init() {

println("init ")

self.uuid = "XXX"

self.uuid = Device.createUUID()

println(self.uuid)

}

class func createUUID() -> String{
return "XXX2"
}
}


var device = Device()


You can notice that I implemented
createUUID
method as static.

But why I can't call this method from
init
not in static way? :

class Serializable : NSObject{
override init() { }
}

class Device : Serializable{

var uuid:String

override init() {

// tried
// super.init()

println("init ")

self.uuid = "XXX"

self.uuid = self.createUUID() // ERROR
self.uuid = createUUID() // ERROR

println(self.uuid)

// tried
// super.init()

}

func createUUID() -> String{
return "XXX2"
}
}


var device = Device()





Without inheritance it works properly:

class Device {

var uuid:String

init() {

println("init ")

self.uuid = "XXX"

self.uuid = self.createUUID()

println(self.uuid)

}

func createUUID() -> String{
return "XXX2"
}
}


var device = Device()

Answer

There are two competing initialization safety checks that are causing your problem.

Safety check 1

A designated initializer must ensure that all of the properties introduced by its class are initialized before it delegates up to a superclass initializer.

and

Safety check 4

An initializer cannot call any instance methods, read the values of any instance properties, or refer to self as a value until after the first phase of initialization is complete.

Here is how it works.

override init() {
    super.init() // Fails safety check 1: uuid is not initialized.
    uuid = createUUID()
}

conversely,

override init() {
    uuid = createUUID() // Fails safety check 4: cannot call an instance method before initialization is complete.
    super.init()
}

Thanks to @Ruben in his answer