Объект X класса Y не реализует methodSignatureForSelector в Swift



у меня есть класс человек, который создается несколько раз.Каждый человек получает свой собственный таймер. По моему init на Person Я называю 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)")
}
...
...
}


поэтому у меня может быть 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


Я читал в другом месте что я должен наследовать от NSObject но это в Swift не Obj-C. функция находится в классе, поэтому я не уверен, что делать.

453   3  

3 ответов:

Не думал о NSObject как класс Objective-C, подумайте об этом как о классе Cocoa/Foundation. Несмотря на то, что вы используете Swift вместо Objective-C, вы все еще используете все те же фреймворки.

два варианта: (1) добавить dynamic атрибут функции, на которую вы хотите ссылаться в качестве селектора:

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

или (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()
    }
}

начиная с xcode6 beta 6, Вы можете использовать 'dynamic' func

dynamic func timerTick() { .... }

у меня была похожая ошибка при попытке использовать let encodedArchive = NSKeyedArchiver.archivedDataWithRootObject(archive) as NSData где архив был массив пользовательского класса. Я обнаружил, что объявление этого пользовательского класса в качестве подкласса NSObject и NSCoding сделало трюк. Для этого потребуется еще несколько строк, чтобы соответствовать протоколу NSCoding, поэтому он будет выглядеть примерно так:

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

  func encodeWithCoder(_aCoder: NSCoder) {   }
}

Comments

    Ничего не найдено.