swift2 - Adding a failable initializer with the same signature as super class's convenience initializer (Swift) -
i know why cant define init?() subview. compiler warms me failable initializer 'init()' cannot override non-failable initializer. understanding convenience init not treat override in subclass compile warm me if add override init?() initializer not override designated initializer superclass.
my expectation subview.init?() should not treat override view.init() subview should not have convenience initializer inherited subview.init() in first place.
import foundation import uikit class view { convenience init() { self.init(frame: cgrectzero) } init(frame: cgrect) { } required init?(coder adecoder: nscoder) { } } class subview: view { private var value: string! init?() { super.init(frame: cgrectzero) } required init?(coder adecoder: nscoder) { fatalerror("init(coder:) has not been implemented") } }
see 'self explanatory' example
class base { var i:int init?(i: int){ self.i = if == 0 { return nil } } convenience init() { self.init(i: 1)! } } class c: base { override init?(i: int){ super.init(i: 2 * i) } } var c: c? = c() // c automatically inherits convenience init() superclass c?.i == 2 // true !!!!! // why class d: base { init?() { // error: failable initializer 'init()' cannot override non-failable initializer } } update
from our discussion think, 'missing glue' in proper understanding initialization in swift interpretation of 'convenience' attribute / keyword. difference between init() , convenience init() ? if don't provide designated initializer, swift use default one, can interpreted signature init(){} /no parameters/. if define our own version of init(){ .... }, compiler use our version. in designated init(){ ... } or init?(){ ... } not able reference self, in convenience init(){ ... } or convenience init?() { ... } can , it. otherwise convenience not necessary there. initializer compiler use, if going define 2 of them same signature /same parameters/? there no chance choose it!
// expectation wrong, // because initializer not other methods class c { var i: int? // compiles here, see usage below! func foo()->int { = 1 return i! } func foo()->int? { = nil return } // convenience or not, doesn' matter init() { = 1 } // next lines compiler complains // because have same signature / same parameters / // code call 3 initializers // same way // // let c = c() // // dynamictype of c depends of relsut of class constructor (initializer). // result anyway reference, not value. // c variable or constant (probably optional) value // refernce created instance (and 'null reference') // nil special value in swift , differs 'null reference' // in case of fail-able initializer c must optional or implicitlyinwrappedoptional /* convenience init?() { self.init() } init?() { return nil } */ } let c = c() let p1: int = c.foo() // 1 let p2: int? = c.foo() // nil //let p = c.foo() // error: ambiguous use of 'foo()' class d { var i:int? init() { = 1 } } // theory, compiler 'smart' enough choose // right version of initializer, have strong // consequences language well. let d1: d = d() let d2: d? = d() d1.i // 1 d2?.i // 1 // 1 valid if use fail-able version of init class e { var i:int? init?() { = 1 } } let e1: e? = e() e1?.i // 1 //let e2:e = e() // error: value of optional type 'e?' not unwrapped
Comments
Post a Comment