NSTimer不在后台设备上工作

时间:2014-09-13 16:19:27

标签: xcode nstimer background-process

我试图在后台运行一些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];
            });
        }
    }

}

问题是在真实设备上它不起作用,我应该启用一些后台模式吗?

1 个答案:

答案 0 :(得分:2)

有几个问题:

  1. NSTimer需要一个运行循环,无法从后台全局工作线程调度(除非您在mainRunLoop上安排它,或者在某个后台线程上手动创建一个运行循环)。 / p>

    如果您需要在后台线程中运行countdown方法,则可以使用调度计时器。或者,更简单,只需在主运行循环上安排计时器。

  2. 您正在创建后台任务,但在创建倒计时重复计时器时会立即终止它。在你的有限长度任务完成之前,你可能不希望终止后台任务。

    注意,如果您通过Xcode中的调试器运行应用程序,这可能会影响后台任务,应用程序终止等行为(链接到调试器的过程会使应用程序保持活动状态)。确保您在设备上测试应用程序,而不是按Xcode中的“go”按钮,但确保应用程序已终止,然后手动点击设备“主页”屏幕上的应用程序图标。

  3. 您的倒计时器有多长时间?这个后台任务机制是为有限长度的任务而设计的(例如我认为它目前给你3分钟左右)。

  4. 如果您的后台计时器可能持续时间较长,您可能只想安排local notification让用户知道指定的计时器间隔何时过去。

    注意,无论如何,这可能是在后台运行“计时器”的更明智的模型。而不是让app在后台旋转(占用CPU周期和电池),只需指定何时应将本地通知传递给用户并完全绕过后台任务模式。