[英]invalidate NSTimer inside dispatch_async
我正在创建一个游戏,在游戏中我需要一个时间计数器。
我的作品很棒,但是当我滚动地图时它会停止,然后在我滚动完成时它会再次开始。 我用dispatch_async修复了这个问题。 这是代码
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeNext) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
});
计时器:
__block NSTimer *timer;
但是,如果应用程序进入后台,则我需要停止此时间(并且当它激活时会再次启动)。
通过这种方式,我可以滚动地图,并且计时器可以很好地工作:
- (void)timeNext {
[timer invalidate];
}
没用 有人知道如何停止吗? 或完成此任务的任何其他想法?
不要在全局队列的线程上创建计时器,然后在该线程上启动运行循环。
只需在主线程(主运行循环)上创建计时器,然后将其添加到跟踪运行循环模式即可。 可以将计时器添加到多个运行循环模式。
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeNext) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
如果您使用UIScrollView在游戏世界中滚动,则滚动滚动跟踪触摸时计时器将暂停-您需要设置计时器以将其用于其他模式UITrackingRunLoopMode
,例如
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
代替
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
这将允许您的计时器在滚动等控件跟踪用户触摸时触发事件。
[编辑]
您创建计时器,例如通过
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
然后将此计时器添加到runloop中(基本上,应该将其添加到应用主runloop中):
NSTimer* timer = [NSTimer timerWithTimeInterval:1./60. target:self selector:@selector(tick) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
我使用NSRunLoopCommonModes
而不是UITrackingRunLoopMode
,一切看起来都很好。 主线程ui操作将不再阻止tick
功能。
NSTimer* timer = [NSTimer timerWithTimeInterval:1./60. target:self selector:@selector(tick) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.