我有一个在 5 秒内触发的计时器添加到全局队列中,尽管我在 2 秒后使其无效,但运行循环直到 5 秒才会终止。在下面的代码片段中,backgroundTimer是一个实例var,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 创建来为后台队列提供服务)can这样做,但这有点没有意义。
除此之外,您说过您想要发生的是让这个运行循环退出,但是在文档中-run
方法,它说如下:
从运行循环中手动删除所有已知的输入源和计时器
并不能保证运行循环会退出。 OS X 可以安装并
根据需要删除其他输入源以处理目标请求
在接收者的线程上。因此,这些来源可以防止
run 循环退出。
如果您希望运行循环终止,则不应使用此方法。
相反,使用其他运行方法之一并检查其他
循环中您自己的任意条件。
如果您想在计时器无效时退出事件循环,则需要自己旋转事件循环。例如:
while (_backgroundTimer.valid && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow: 0.1]]);
这将在计时器失效后最多 0.1 (- epsilon) 秒内退出运行循环。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)