Ich habe eine Klasse Person, die mehrmals instanziiert wird. Jede Person bekommt ihren eigenen Timer. Nach meiner init
für Person
Ich nenne 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)")
}
...
...
}
Ich kann also 3 Instanzen von Person in einem Array von haben Person[]
. Ich erhalte eine Fehlermeldung:
2014-06-25 13:57:14.956 ThisProgram[3842:148856] *** NSForwarding: warning: object 0x113760048 of class '_TtC11ThisProgram6Person' does not implement methodSignatureForSelector: -- trouble ahead
Ich habe an anderer Stelle gelesen, dass ich von erben sollte, NSObject
aber dies ist in Swift nicht Obj-C. Die Funktion befindet sich innerhalb der Klasse, daher bin ich mir nicht sicher, was ich tun soll.
class Person : NSObject { ... }
. Suchen Sie eine andere Lösung?Antworten:
Stellen Sie sich das nicht
NSObject
als Objective-C-Klasse vor, sondern als Cocoa / Foundation-Klasse. Auch wenn Sie Swift anstelle von Objective-C verwenden, verwenden Sie immer noch dieselben Frameworks.Zwei Optionen: (1) Fügen Sie das
dynamic
Attribut der Funktion hinzu , auf die Sie als Selektor verweisen möchten:Oder (2)
Person
als Unterklasse von deklarierenNSObject
und dann einfachsuper.init()
am Anfang Ihres Initialisierers aufrufen :quelle
@objc func timerTick()
. Die NSTimer-API scheint ziemlich abhängig von der Obj-C-Laufzeit zu sein.NSTimer
Verwendet die Nachrichtenweiterleitung, um den Zielselektor aufzurufen. Dies ist eine Objective-C-Funktion, die bei Swift-Typen standardmäßig nicht behandelt wird. Wenn Sie das@objc
Attribut verwenden oder von einer Objective-C-Klasse erben, entscheiden Sie sich für mehrere Funktionen, einschließlich der Nachrichtenweiterleitung.dynamic
. Sie sind beide gut und beide funktionieren immer noch, aber die Verwendungdynamic
dieser einen Funktion kann als leichterer Ansatz angesehen werden.Seit XCode6 Beta 6 können Sie 'dynamische' Funktionen verwenden
quelle
Ich hatte einen ähnlichen Fehler beim Versuch,
let encodedArchive = NSKeyedArchiver.archivedDataWithRootObject(archive) as NSData
das Archiv als Array einer benutzerdefinierten Klasse zu verwenden. Ich fand, dass das Deklarieren dieser benutzerdefinierten Klasse als Unterklasse von NSObject und NSCoding den Trick machte. Es werden einige weitere Zeilen erforderlich sein, um dem Protokoll der NSCoding zu entsprechen, sodass es zunächst ungefähr so aussieht:quelle