NSTimer not firing when runloop is blocked

前端 未结 2 1226
长发绾君心
长发绾君心 2020-12-02 18:53

I am just about finished with my app and beta testing found a bug in the stopwatch portion... The stopwatch uses an nstimer to do the counting and has a table for storing la

相关标签:
2条回答
  • 2020-12-02 19:30

    bbum's answer provides a better way to design your application, but if you want your timer to fire regardless of whether the user is manipulating the UI or not you'll need to add it to the tracking mode of the runloop.

    Assuming that you're developing for the iPhone, that mode is UITrackingRunLoopMode. If you're developing for the Mac there is a similarly named NSEventTrackingRunLoopMode.

    NSRunLoop *runloop = [NSRunLoop currentRunLoop];
    NSTimer *timer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(myTimerAction:) userInfo:nil repeats:YES];
    [runloop addTimer:timer forMode:NSRunLoopCommonModes];
    [runloop addTimer:timer forMode:UITrackingRunLoopMode];
    
    0 讨论(0)
  • 2020-12-02 19:47

    If the event loop isn't running, any timers will not fire until the event loop can run again. Even if the event loop isn't block, the timer isn't guaranteed to fire at exactly its configured interval. If your timings were based entirely on timers firing, the amount of error will grow over time.

    You need to keep track of the duration separately from the firing of the timers. Each time a timer fires, recalculate your duration and redisplay.

    For a start/pause/restart/stop type of setup, you generally want to:

    • grab the time upon start (either as an NSDate instance or as an NSTimeInterval value)

    • upon pause or stop, grab the time upon pause/stop. Subtract the start time from this time and you have the interval's duration

    • upon restart, grab the time upon restart but also keep around the already elapsed duration

    • upon pause/stop, grab the time at pause/stop and add the already elapsed duration

    In general, doing all of this with NSTimeInterval values -- which are just doubles -- is easiest. However, if you need to keep track of the actual moment in time when the events happened, use NSDate instances instead.

    0 讨论(0)
提交回复
热议问题