I have the following instance method in my Swift class Sentence
which makes a call to a NSTimer
which calls the class instance method as its Selector. When I run the program without breakpoints, it gets to the first NSTimer
successfully but then stalls at NSTimer
. When I add a breakpoint to see if sentenceDidFinish
is ever called, I see that it never is, proving it stops at the first NSTimer
.
class Sentence : NSObject {
//init() etc.
func playEvent(eventIndex : Int){
if (eventIndex < 2){
let currEvent = self.eventArray[eventIndex]
currEvent.startEvent()
let nextIndex = eventIndex + 1
print("Play Event event id is ", eventIndex)
NSTimer.scheduledTimerWithTimeInterval(currEvent.duration, target: self, selector: Selector("playEvent:"), userInfo: NSNumber(integer: nextIndex), repeats: false)
}
else if (eventIndex==2){
self.eventArray[eventIndex].startEvent()
print("Play Event event id is ", eventIndex)
NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: Selector("sentenceDidFinish"), userInfo: nil, repeats: false)
}
else{
//DO Nothing
}
}
func sentenceDidFinish(){
//foo
//bar
}
}
Here is the full .swift file:
When you call playEvent:
with the timer, the argument passed will be the timer itself, not the integer. But in the declaration for eventIndex
you are acting as if it will be the integer.
Try adding a method like this:
func handleTimer(timer: NSTimer) {
playEvent(timer.userInfo as! Int)
}
Then call the first timer like this:
NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: "handleTimer:", userInfo: NSNumber(integer: nextIndex), repeats: false)
The forced casting (as!
) will crash if userInfo
isn't castable to Int
. Safer, but more verbose would look like:
func handleTimer(timer: NSTimer) {
guard let index = timer.userInfo as? Int else { return }
playEvent(index)
}