即使应用程序被推送到后台,我也需要完成一项长时间运行的任务。从文档中我可以看到,执行此操作的方法是使用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;
});
现在我明白第二个代码块是异步执行的,一旦完成,应用程序就会被通知并且任务被标记为无效,但是,任何人都可以告诉我在什么情况下第一个代码块被执行以及第一个代码块是如何执行的第二块被关联?是不是因为我已经开始了一项任务,而且我接下来要做的就是调用dispatch_async这两个块会被关联吗?
答案 0 :(得分:5)
这些块与任何“神奇”方式无关。
第二个块将排队并异步运行,如您所述。第一个块将only ever be called by the system if:
[self doChunkOfWork]
区块超过大约10分钟(在当前iOS版本上)。如果-doChunkOfWork
阻止,[application endBackgroundTask:bgTask]
将永远不会被调用,系统会正确! - 认为你还在做工作。 iOS设置了在后台工作的时间限制,如果超出此限制,它将调用到期处理程序(第一个块)。
您到期处理程序的当前实现会立即将任务标记为已完成。此时,您的应用程序将不再执行,如果doChunkOfWork
仍在继续,它将被暂停。 (实际上,所有应用程序的线程都将暂停。)
在将来的某个时间,用户可能会切换回您的应用。然后你的线程将被恢复,doChunkOfWork
将继续执行它所在的位置。