Tengo una persona de clase que se instancia varias veces.Cada persona tiene su propio temporizador. Sobre en mi init
porque Person
llamo startTimer()
.
class Person {
var timer = NSTimer()
func startTimer() {
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("timerTick"), userInfo: nil, repeats: true)
}
func timerTick() {
angerLevel++
println("Angry! \(angerLevel)")
}
...
...
}
Entonces puedo tener 3 instancias de Person en una matriz de Person[]
. Recibo un error:
2014-06-25 13:57:14.956 ThisProgram[3842:148856] *** NSForwarding: warning: object 0x113760048 of class '_TtC11ThisProgram6Person' does not implement methodSignatureForSelector: -- trouble ahead
Leí en otra parte que debería heredar, NSObject
pero esto está en Swift, no en Obj-C. La función está dentro de la clase, así que no estoy seguro de qué hacer.
class Person : NSObject { ... }
. ¿Buscas una solución diferente?Respuestas:
No pienses
NSObject
en una clase de Objective-C, piensa en ella como una clase Cocoa / Foundation. Aunque esté usando Swift en lugar de Objective-C, todavía está usando los mismos marcos.Dos opciones: (1) agregue el
dynamic
atributo a la función a la que desea hacer referencia como selector:dynamic func timerTick() { self.angerLevel++ print("Angry! \(self.angerLevel)") }
O (2) declare
Person
como una subclase deNSObject
, luego simplemente llamesuper.init()
al comienzo de su inicializador:class Person: NSObject { var timer = NSTimer() var angerLevel = 0 func startTimer() { print("starting timer") timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "timerTick", userInfo: nil, repeats: true) } func timerTick() { self.angerLevel++ print("Angry! \(self.angerLevel)") } override init() { super.init() self.startTimer() } }
fuente
@objc func timerTick()
. La API de NSTimer parece depender bastante del tiempo de ejecución de Obj-C.NSTimer
utiliza el reenvío de mensajes para llamar al selector de destino, que es una función de Objective-C que no se maneja en los tipos Swift de forma predeterminada. Cuando usa el@objc
atributo o hereda de una clase Objective-C, está optando por varias funciones, incluido el reenvío de mensajes.dynamic
. Ambos son buenos y aún funcionan, pero el usodynamic
de esta función puede verse como un enfoque más ligero.Desde XCode6 beta 6, puede usar la función 'dinámica'
dynamic func timerTick() { .... }
fuente
Tuve un error similar al intentar usar
let encodedArchive = NSKeyedArchiver.archivedDataWithRootObject(archive) as NSData
donde el archivo era una matriz de una clase personalizada. Descubrí que declarar esa clase personalizada como una subclase de NSObject y NSCoding funcionó. Requerirá algunas líneas más para cumplir con el protocolo de NSCoding, por lo que se verá así para empezar:class Person: NSObject, NSCoding { init() { super.init() } func encodeWithCoder(_aCoder: NSCoder) { } }
fuente