我在全局队列中添加了一个在 5 秒内触发的计时器,但我在 2 秒后使它无效运行循环直到 5 秒才会终止。在下面的代码片段中,backgroundTimer 是一个实例变量,run 是一个成员函数。以下阻止运行循环终止的代码有什么问题。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
_backgroundTimer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(run) userInfo:nil repeats:NO];
[ [NSRunLoop currentRunLoop] addTimer:_backgroundTimer forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] run];
NSLog(@"Run loop terminated");
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[_backgroundTimer invalidate];
_backgroundTimer=nil;
});
最佳答案
这里的第一个问题是您的计时器被添加到某个任意后台线程的运行循环中。 (即线程将由 GCD 创建以服务于后台队列)您可以这样做,但这有点没有意义。
除此之外,您说过您想要发生的是退出此运行循环,但在 -run
方法的文档中,它表示如下:
Manually removing all known input sources and timers from the run loop is not a guarantee that the run loop will exit. OS X can install and remove additional input sources as needed to process requests targeted at the receiver’s thread. Those sources could therefore prevent the run loop from exiting.
If you want the run loop to terminate, you shouldn't use this method. Instead, use one of the other run methods and also check other arbitrary conditions of your own, in a loop.
如果你想在定时器无效时退出它,你将需要自己旋转事件循环。例如:
while (_backgroundTimer.valid && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow: 0.1]]);
这将在计时器失效后最多 0.1(- epsilon)秒退出运行循环。
关于objective-c - 如何立即从runloop中删除定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27500802/