当设备进入后台时,我有一个计时器在运行,因为我想检查服务中的少量数据。我在应用程序委托的applicationDidEnterBackground方法中使用以下代码
UIApplication *app = [UIApplication sharedApplication];
//create new uiBackgroundTask
__block UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
//and create new timer with async call:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//run function methodRunAfterBackground
NSString *server = [variableStore sharedGlobalData].server;
NSLog(@"%@",server);
if([server isEqual:@"_DEV"]){
arrivalsTimer = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(getArrivals) userInfo:nil repeats:YES];
}
else {
arrivalsTimer = [NSTimer scheduledTimerWithTimeInterval:300 target:self selector:@selector(getArrivals) userInfo:nil repeats:YES];
}
[[NSRunLoop currentRunLoop] addTimer:arrivalsTimer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
});
这绝对可以正常工作,直到设备自动锁定,然后计时器停止计时。关于如何阻止这种情况的任何建议?默认的直播时间是5分钟,因此大多数设备都将被锁定很长时间,甚至不会触发一次。
谢谢
一些观察:
正如H先生所指出的,beginBackgroundTaskWithExpirationHandler
在现代iOS版本中,仅给您三分钟(180秒)的时间。因此,尝试在五分钟内触发计时器不会成功。
您可以[[UIApplication sharedApplication] backgroundTimeRemaining]
用来查询还剩多少时间。
设备锁定后,后台任务继续。您不应看到该应用终止。如果用户通过“双击主屏幕按钮并在任务切换器屏幕上向上滑动”手动终止应用程序,则将终止后台任务,而不仅仅是锁定设备。
关于计时器的一些评论:
该代码将计时器添加到后台队列。通常没有必要。仅仅因为该应用程序处于后台状态,您仍然可以继续将主运行循环用于计时器等。
因此,只需scheduledTimerWithTimeInterval
从主线程进行调用就可以完成。除非绝对必要,否则在运行循环中使用GCD工作线程是没有意义的(即使那样,我可能会创建自己的线程并向其中添加运行循环)。
顺便说一句,如果绝对需要在某个后台调度队列上调度计时器,那么使用调度计时器可能会更容易。它完全消除了运行循环的要求。
顺便说一句,它不适合使用scheduledTimerWithTimeInterval
有addTimer
。您调用scheduledTimerWithTimeInterval
创建一个计时器并将其添加到当前运行循环中。如果要将其添加到另一个运行循环中,timerWithTimeInterval
请使用,然后调用addTimer
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句