2

我正在创建一个游戏,在游戏中我需要一个计时器。

我工作得很好,但是当我滚动地图时它会停止,然后当我完成滚动时它会重新开始。我用 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];
    }

并没有工作。有谁知道如何阻止它?或任何其他想法来完成这项任务?

4

3 回答 3

4

不要在全局队列的线程上创建计时器,然后在该线程上启动运行循环。

只需在主线程(主运行循环)上创建计时器,并将其添加到跟踪运行循环模式。可以将计时器添加到多个运行循环模式。

timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self  selector:@selector(timeNext) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
于 2013-04-18T04:56:47.880 回答
1

如果您使用 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;

然后将此计时器添加到运行循环(基本上,您应该将其添加到您的应用程序主运行循环):

NSTimer* timer = [NSTimer timerWithTimeInterval:1./60. target:self selector:@selector(tick) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
于 2013-04-18T04:47:03.607 回答
0

我使用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];
于 2015-05-26T06:04:06.347 回答