iOS:何时调用结束后台任务代码块?

Ell*_*lis 4 ios

我有一个长期运行的任务,我想完成,即使应用程序被推到后台.从文档中我可以看到,执行此操作的方法是使用beginBackgroundTaskWithExpirationHandler:功能并异步启动正在运行的任务,如以下代码段所示:

UIApplication* application = [UIApplicationsharedApplication];
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
    // Clean up any unfinished task business by marking where you.
    // stopped or ending the task outright.

    [application endBackgroundTask: bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // Do the work associated with the task, preferably in chunks.
         for (int i = 0; i < 3; i++){

        [self doChunkOfWork];
    }

    // end work
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
});
Run Code Online (Sandbox Code Playgroud)

现在我明白第二个代码块是异步执行的,一旦完成,应用程序就会被通知并且任务被标记为无效,但是,任何人都可以告诉我在什么情况下第一个代码块被执行以及第一个和第二个块如何获得相关?是不是因为我已经启动了一个任务,而且我接下来要做的就是调用dispatch_async这两个块会关联吗?

Phi*_*vin 5

这些块与任何"神奇"方式无关.

正如您所述,第二个块将排队并异步运行.在以下情况下,系统只会调用第一个块:

  1. 应用程序被发送到后台(即,用户切换到另一个应用程序)
  2. 你的第二个块的[self doChunkOfWork]块超过大约10分钟(在当前的iOS版本上).

如果-doChunkOfWork块,[application endBackgroundTask:bgTask]将永远不会被调用,系统将正确! - 思考你仍然在做工作.iOS设置了在后台工作的时间限制,如果超出此限制,它将调用您的到期处理程序(第一个块).

您当前的到期处理程序实现会立即将任务标记为已完成.此时,您的应用程序将不再执行,如果doChunkOfWork仍在继续,它将被暂停.(实际上,所有应用程序的线程都将暂停.)

在将来的某个时间,用户可能会切换回您的应用程序.然后您的线程将恢复,doChunkOfWork并将继续执行它的位置.

  • 值得注意的是,如果完成上述所有操作后,`doChunkOfWork`仍在继续,则下次您的应用程序后台处理时,系统将不会给您额外的时间,因为您的到期处理程序已将任务标记为已完成.这可能不是你想要的. (2认同)