Objeto X da class Y não implementa methodSignatureForSelector no Swift

Eu tenho uma pessoa da class que é instanciada várias vezes. Cada pessoa recebe seu próprio timer. Após no meu init para Person eu chamo 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)") } ... ... } 

Então eu posso ter 3 instâncias de Person em uma matriz de Person[] . Estou recebendo um erro:

 2014-06-25 13:57:14.956 ThisProgram[3842:148856] *** NSForwarding: warning: object 0x113760048 of class '_TtC11ThisProgram6Person' does not implement methodSignatureForSelector: -- trouble ahead 

Eu li em outro lugar que eu deveria herdar do NSObject mas isso está em Swift e não em Obj-C. A function está dentro da class, então não tenho certeza do que fazer.

Não pense no NSObject como uma class Objective-C, pense nisso como uma class Cocoa / Foundation. Mesmo que você esteja usando o Swift em vez do Objective-C, você ainda está usando as mesmas estruturas.

Duas opções: (1) adicione o atributo dynamic à function que você deseja referenciar como seletor:

  dynamic func timerTick() { self.angerLevel++ print("Angry! \(self.angerLevel)") } 

Ou (2) declare Person como uma subclass de NSObject , então apenas chame super.init() no início do seu 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() } } 

Desde o XCode6 beta 6, você pode usar a function ‘dinâmica’

 dynamic func timerTick() { .... } 

Eu tive um erro semelhante tentando usar let encodedArchive = NSKeyedArchiver.archivedDataWithRootObject(archive) as NSData onde archive era uma matriz de uma class personalizada. Descobri que declarar que class customizada como uma subclass de NSObject e NSCoding fazia o truque. Isso exigirá mais algumas linhas para se adequar ao protocolo do NSCoding, então será algo como isto para começar:

 class Person: NSObject, NSCoding { init() { super.init() } func encodeWithCoder(_aCoder: NSCoder) { } }