Saya memiliki kelas Person yang dipakai beberapa kali. Setiap orang memiliki pengatur waktunya sendiri. Setelah di saya init
untuk Person
saya panggil 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)")
}
...
...
}
Jadi saya mungkin memiliki 3 contoh Person dalam sebuah array Person[]
. Saya mendapatkan kesalahan:
2014-06-25 13:57:14.956 ThisProgram[3842:148856] *** NSForwarding: warning: object 0x113760048 of class '_TtC11ThisProgram6Person' does not implement methodSignatureForSelector: -- trouble ahead
Saya membaca di tempat lain bahwa saya harus mewarisi NSObject
tetapi ini di Swift bukan Obj-C. Fungsinya ada di dalam kelas jadi saya tidak yakin apa yang harus dilakukan.
class Person : NSObject { ... }
. Apakah Anda mencari solusi lain?Jawaban:
Jangan anggap
NSObject
sebagai kelas Objective-C, anggap saja sebagai kelas Cocoa / Foundation. Meskipun Anda menggunakan Swift dan bukan Objective-C, Anda masih menggunakan semua kerangka kerja yang sama.Dua opsi: (1) tambahkan
dynamic
atribut ke fungsi yang ingin Anda rujuk sebagai pemilih:dynamic func timerTick() { self.angerLevel++ print("Angry! \(self.angerLevel)") }
Atau (2) nyatakan
Person
sebagai subclass dariNSObject
, lalu panggil sajasuper.init()
di awal penginisialisasi Anda: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() } }
sumber
@objc func timerTick()
. NSTimer API tampaknya sangat bergantung pada Obj-C Runtime.NSTimer
menggunakan penerusan pesan untuk memanggil pemilih yang ditargetkan, yang merupakan fitur Objective-C yang tidak ditangani pada tipe Swift secara default. Saat Anda menggunakan@objc
atribut atau mewarisi dari kelas Objective-C, Anda memilih ke dalam beberapa fitur, termasuk penerusan pesan.dynamic
. Keduanya bagus dan keduanya masih berfungsi, tetapi menggunakandynamic
fungsi yang satu ini mungkin terlihat pendekatan yang lebih ringan.Sejak XCode6 beta 6, Anda dapat menggunakan fungsi 'dinamis'
dynamic func timerTick() { .... }
sumber
Saya mengalami kesalahan serupa saat mencoba menggunakan di
let encodedArchive = NSKeyedArchiver.archivedDataWithRootObject(archive) as NSData
mana arsip adalah array kelas khusus. Saya menemukan bahwa mendeklarasikan kelas khusus itu sebagai subkelas NSObject dan NSCoding berhasil. Ini akan membutuhkan beberapa baris lagi untuk menyesuaikan dengan protokol NSCoding sehingga akan terlihat seperti ini untuk memulai:class Person: NSObject, NSCoding { init() { super.init() } func encodeWithCoder(_aCoder: NSCoder) { } }
sumber