multiple herencia constructores clases objective-c swift

objective-c - constructores - herencia swift 4



¿Cómo puedo devolver el tipo de instancia en Swift (4)

Esta pregunta ya tiene una respuesta aquí:

Quiero hacer una extensión de alguna clase para devolver el objeto de tipo runtime

por ejemplo, creo extenstion de clase A

extension A { class func niceObject() -> XXXXX { // in objective-c is instancetype return .... } }

Así que cualquiera sabe que hay una palabra clave de tipo de instancia en Swift o que no reemplaza a xxxxx y puedo llamar a esta función en la subclase de A sin realizar la conversión manual

var b: B = B.niceObject()

Gracias


Al menos en procotols, puedes usar el Self . Esto representa el tipo real de self . Aunque no estoy seguro de las extensiones ...

Por ejemplo, vea la definición de Equatable :

protocol Equatable { func ==(lhs: Self, rhs: Self) -> Bool }


Cuando usa una API Swift de Objective-C, el compilador normalmente realiza una traducción directa. Por ejemplo, la func playSong(name: String) Swift API func playSong(name: String) se importa como - (void)playSong:(NSString *)name en Objective-C.

Sin embargo, hay una excepción: cuando usa un inicializador Swift en Objective-C, el compilador agrega el texto " initWith " al comienzo del método y escribe correctamente el primer carácter en el inicializador original.

Por ejemplo, este inicializador Swift init (songName: String, artist: String) se importa como - (instancetype)initWithSongName:(NSString *)songName artist:(NSString *)artist en Objective-C


Hay una palabra clave Self que se permite en dos lugares: en los protocolos (consulte la respuesta de Jean-Philippe Pellet) y como resultado de class métodos de class :

extension A { class func niceObject() -> Self? { return nil } }

Desafortunadamente, esto no te ayudará porque lo siguiente no es válido

extension A { class func niceObject() -> Self? { //A can''t be converted to Self return A() } }

El error se debe al hecho de que cuando hereda de A

class B : A { }

entonces

var b = B.niceObject()

en realidad devolvería una instancia A que no es convertible a Self ( Self es B )

@Grimxn encontró la solución correcta ( ver su respuesta ):

Debe agregar un inicializador requerido a la clase base, por ejemplo,

class A { @required init() { } }

y luego puedes llamar al inicializador usando self()

extension A { class func niceObject() -> Self { return self() } }


Puedes hacerlo. Código de juegos a continuación. Es self () que niceObject () tiene que devolver. Además, debe tener un init required en la clase base.

class A { required init() { } func whatClassAmI() -> String { return "Class A" } } class B: A { required init() { super.init() } override func whatClassAmI() -> String { return "Class B" } } let a = A() let sa = a.whatClassAmI() // "Class A", of course let b = B() let sb = b.whatClassAmI() // "Class B", of course extension A { class func niceObject() -> Self { return self.init() } } let aa = A.niceObject() let saa = aa.whatClassAmI() // "Class A" let bb = B.niceObject() let sbb = bb.whatClassAmI() // "Class B", as required