NSTimer and NSRunLoop

random picture random · Jul 26, 2012 · Viewed 7.3k times · Source

My app tracks a user with CLLocationManager. In the delegate call didUpdateToLocation I do all the fun stuff of saving their position. However, I needed a way to test if they had stopped. That away I could stop recording locations and consider their trip over. So I have a NSTimer in CCLocationManager that gets added and removed every time didUpdateToLocation is called. That away it will be initiated when the user stops and CLLocationManager stops getting called.

The only way that I could ever get the NSTimer to work is to do:

[[NSRunLoop mainRunLoop] addTimer:userStoppedMovingTimer forMode:NSRunLoopCommonModes];

Then to remove it:

[userStoppedMovingTimer invalidate];

I've never had to add timers like this in the past. Could someone shed some light as to why this is?

Answer

Tom Dalling picture Tom Dalling · Jul 26, 2012

From the documentation:

There are three ways to create a timer:

  1. Use the scheduledTimerWithTimeInterval:invocation:repeats: or scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: class method to create the timer and schedule it on the current run loop in the default mode.

  2. Use the timerWithTimeInterval:invocation:repeats: or timerWithTimeInterval:target:selector:userInfo:repeats: class method to create the timer object without scheduling it on a run loop. (After creating it, you must add the timer to a run loop manually by calling the addTimer:forMode: method of the corresponding NSRunLoop object.)

  3. Allocate the timer and initialize it using the initWithFireDate:interval:target:selector:userInfo:repeats: method. (After creating it, you must add the timer to a run loop manually by calling the addTimer:forMode: method of the corresponding NSRunLoop object.)

You were probably using option 1 previously, and now you're using option 2 or 3.