Question Summary:
If you have a Swift class that takes a selector as an argument in its initializer, how do you manually "fire/call" that selector?
Full Question:
Consider the following attempt at making a custom timer in Swift:
let TIME_INTERVAL = 0.1 class ValueAnimator : NSObject { private var timer = Timer() private let maxRep: Int private var currentRepIndex: Int = 0 private var selector: Selector init(durationInSeconds: Int, selector: Selector) { print("VALUEANIMATOR INIT") self.maxRep = Int(Double(durationInSeconds) / TIME_INTERVAL) self.selector = selector } func start() { timer = Timer.scheduledTimer(timeInterval: TIME_INTERVAL, target: self, selector: (#selector(timerCallback)), userInfo: nil, repeats: true) } @objc func timerCallback() { currentRepIndex += 1 perform(selector) // <-------- this line causes crash, "unrecognized selector sent to instance 0x600001740030" print ("VA timer called!, rep: \(currentRepIndex)") if currentRepIndex == maxRep { timer.invalidate() print("VA timer invalidated") } } } The usage of this "ValueAnimator" would be similar to a normal Timer/NSTimer, in that you pass a "selector" as an argument and that selector is called each time the ValueAnimator fires:
[In Parent Class]:
// { ... let valueAnimatorTest = ValueAnimator(durationInSeconds: 10, selector: #selector(self.temp)) valueAnimatorTest.start() } @objc func temp() { print("temp VA callback works!") // this doesn't happen :( } I'm trying to implement the same thing and as I understand, the line:
perform(selector) should fire the selector in the parent class, but instead I get the error: "unrecognized selector sent to instance 0x600001740030"
I'm in a bit over my head here. I have tried googling the error, but everyone seems to be talking about how to use a selector from the parent-side (how to use Timer.scheduledTimer(), etc.) but I already know how to do that successfully.
I've also tried various tweaks to the code (changing public/private, scope of variables, and different forms of the performSelector() function)... but can't figure out the proper way to make the selector fire... or the unrelated mistake I've made if there is one.
Thanks for any help.