我正在尝试在后台运行一些 nstimer,实际上我使用此代码在模拟器上实现了它
- (void)start {
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) {
if ([[UIDevice currentDevice] isMultitaskingSupported]) {
UIApplication *application = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier background_task;
background_task = [application beginBackgroundTaskWithExpirationHandler: ^{
[application endBackgroundTask:background_task];
background_task = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;
if (self.timer == nil) self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(countdown) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
});
}
}
}
问题是在真实设备上它不起作用,也许我应该启用一些后台模式?
最佳答案
几个问题:
NSTimer
需要一个运行循环,无法从后台全局工作线程调度(除非您在mainRunLoop
上调度它,或者在一些后台线程)。如果您需要在后台线程中运行
countdown
方法,则可以使用调度计时器。或者,更简单的是,只需在主运行循环上安排计时器即可。您正在创建后台任务,但在创建倒计时重复计时器时立即终止它。您可能不想在有限长度任务完成之前终止后台任务。
请注意,如果您通过 Xcode 中的调试器运行应用程序,这可能会影响后台任务、应用程序终止等的行为(链接到调试器的进程使应用程序保持事件状态)。确保在设备上测试应用程序,而不是通过按 Xcode 中的“执行”按钮,而是确保应用程序已终止,然后手动点击设备“主”屏幕上的应用程序图标。
您的倒计时器有多长?这种后台任务机制是为有限长度的任务而设计的(例如,我认为它目前给你 3 分钟左右的时间)。
如果您的后台计时器的持续时间可能较长,您可能只想安排 local notification让用户知道指定的计时器间隔何时过去。
请注意,无论如何,这可能是在后台运行“计时器”的更明智的模型。只需指定何时应将本地通知传递给用户并完全绕过后台任务模式,而不是让应用程序在后台旋转(占用 CPU 周期和电池)。
关于xcode - NSTimer 无法在设备后台运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25825165/