我试图在后台运行一些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];
});
}
}
}
问题是在真实设备上它不起作用,我应该启用一些后台模式吗?
答案 0 :(得分:2)
有几个问题:
NSTimer
需要一个运行循环,无法从后台全局工作线程调度(除非您在mainRunLoop
上安排它,或者在某个后台线程上手动创建一个运行循环)。 / p>
如果您需要在后台线程中运行countdown
方法,则可以使用调度计时器。或者,更简单,只需在主运行循环上安排计时器。
您正在创建后台任务,但在创建倒计时重复计时器时会立即终止它。在你的有限长度任务完成之前,你可能不希望终止后台任务。
注意,如果您通过Xcode中的调试器运行应用程序,这可能会影响后台任务,应用程序终止等行为(链接到调试器的过程会使应用程序保持活动状态)。确保您在设备上测试应用程序,而不是按Xcode中的“go”按钮,但确保应用程序已终止,然后手动点击设备“主页”屏幕上的应用程序图标。
您的倒计时器有多长时间?这个后台任务机制是为有限长度的任务而设计的(例如我认为它目前给你3分钟左右)。
如果您的后台计时器可能持续时间较长,您可能只想安排local notification让用户知道指定的计时器间隔何时过去。
注意,无论如何,这可能是在后台运行“计时器”的更明智的模型。而不是让app在后台旋转(占用CPU周期和电池),只需指定何时应将本地通知传递给用户并完全绕过后台任务模式。