这是实施:
__block UIBackgroundTaskIdentifier task = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ [[UIApplication sharedApplication] endBackgroundTask:task]; task = UIBackgroundTaskInvalid; }]; dispatch_queue_t queue = dispatch_queue_create("com.test.test1234",DISPATCH_QUEUE_SERIAL); dispatch_async(queue,^{ // My Task goes here });
在某些情况下,我的串行队列有更多的任务要执行,这些任务无法在系统提供的时间内完成.所以到期块将执行,因为我结束了UIBackgroundTaskIdentifier但没有停止调度过程(我甚至无法取消调度).
Apple的文件说:
Each call to the beginBackgroundTaskWithName:expirationHandler: or beginBackgroundTaskWithExpirationHandler: method generates a unique token to associate with the corresponding task. When your app completes a task,it must call the endBackgroundTask: method with the corresponding token to let the system know that the task is complete. Failure to call the endBackgroundTask: method for a background task will result in the termination of your app. If you provided an expiration handler when starting the task,the system calls that handler and gives you one last chance to end the task and avoid termination.
所以,根据这个,如果我没有调用endBackgroundTask:我的应用程序将被终止,这是好的.
我的问题是:使用我当前的实现,如果我调用endBackgroundTask:在expirationHandler块中,我的调度队列的任务没有完成?我的应用将被终止或暂停?
谢谢
解决方法
场景1:您的应用程序正在Foreground中运行.你开始beginBackgroundTaskWithExpirationHandler然后进入后台模式.你的应用程序保持活力很久.
场景2:您的应用程序正在Foreground中运行.你开始beginBackgroundTaskWithExpirationHandler然后进入后台模式.然后回到Foreground模式并且你没有调用endBackgroundTask然后你的应用程序仍然执行后台队列,因此它将在接下来的3分钟内扩展该过程(在IOS 7介绍之后.在IOS 7之前,过程执行时间是10分钟).所以你必须要取消后台队列和任务从后台队列中出来并进入前台队列.
步骤1:将__block UIBackgroundTaskIdentifier bgTask声明为全局变量.
第2步:在applicationDidEnterBackground中添加以下代码.
- (void)applicationDidEnterBackground:(UIApplication *)application { bgTask = [application beginBackgroundTaskWithExpirationHandler:^{ bgTask = UIBackgroundTaskInvalid; }]; }
- (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. [[UIApplication sharedApplication] endBackgroundTask:bgTask]; }