类Y的对象X没有在Swift中实现methodSignatureForSelector

Joh*_*ton 87 swift

我有一个类Person,它被多次实例化.每个人都得到自己的计时器.当我在initPerson我打电话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)")
 }
...
...
}
Run Code Online (Sandbox Code Playgroud)

所以我可能在一个数组中有3个Person实例Person[].我收到一个错误:

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

我在其他地方读过我应该继承的,NSObject但这是在Swift而不是Obj-C.该功能在课堂内,所以我不知道该怎么做.

Nat*_*ook 160

不要将其NSObject视为Objective-C类,将其视为Cocoa/Foundation类.即使您使用Swift而不是Objective-C,您仍然使用所有相同的框架.

两个选项:(1)将dynamic属性添加到要作为选择器引用的函数:

    dynamic func timerTick() {
        self.angerLevel++
        print("Angry! \(self.angerLevel)")
    }
Run Code Online (Sandbox Code Playgroud)

或者(2)声明Person为子类NSObject,然后super.init()在初始化器的开头调用:

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 您还应该能够像`@objc func timerTick()`一样修饰函数声明.NSTimer API似乎非常依赖于Obj-C运行时. (3认同)
  • 这些解决方案都不再需要.声明选择器函数`dynamic`就足够了.它们都很好并且它们都仍然有效,但在这一个函数上使用`dynamic`可能会被看作是一种更轻量级的方法. (2认同)

小智 32

从XCode6 beta 6开始,你可以使用'dynamic'func

dynamic func timerTick() { .... }
Run Code Online (Sandbox Code Playgroud)


Jer*_*Rea 8

我有一个类似的错误试图使用 let encodedArchive = NSKeyedArchiver.archivedDataWithRootObject(archive) as NSDataarchive是一个自定义类的数组.我发现声明自定义类作为NSObject和NSCoding的子类就可以了.它需要更多的行来符合NSCoding的协议,因此它看起来像这样:

class Person: NSObject, NSCoding {
  init() {
    super.init()
  }

  func encodeWithCoder(_aCoder: NSCoder) {   }
}
Run Code Online (Sandbox Code Playgroud)