在后台IOs7应用程序崩溃
我的应用程序有时在后台崩溃,并显示以下崩溃日志:
Nov 7 12:33:31 iPad backboardd[29] <Warning>: MyApp[3096] has active assertions beyond permitted time: {( <BKProcessAssertion: 0x14680c60> identifier: Called by MyApp, from -[AppDelegate applicationDidEnterBackground:] process: MyApp[3096] permittedBackgroundDuration: 180.000000 reason: finishTask owner pid:3096 preventSuspend preventIdleSleep preventSuspendOnSleep )}
通过其他问题看,我发现崩溃消息表明,我没有正确地结束任务,所以当它的时间到期了操作系统结束它,并崩溃我的应用程序。
所以我加了一些NSLogs:
- (void)applicationDidEnterBackground:(UIApplication *)application { [self saveContext]; [Settings setCallLock:YES]; [self saveStuff]; if ([self isBackgroundTaskNeeded]) { UIApplication* app = [UIApplication sharedApplication]; bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ [self pauseDownloads]; NSLog(@"Debug - Ending background task %d",bgTask); [app endBackgroundTask:bgTask]; NSLog(@"Debug - Background task %d ended",bgTask); bgTask = UIBackgroundTaskInvalid; }]; NSLog(@"Debug - Starting background task %d",bgTask); [self initBackground]; } }
并发现这个任务在坠毁时被调用了两次:
Nov 7 12:30:02 iPad MyApp[3096] <Warning>: Debug - Starting background task 7 Nov 7 12:30:30 iPad MyApp[3096] <Warning>: Debug - Starting background task 8 Nov 7 12:33:26 iPad MyApp[3096] <Warning>: Debug - Ending background task 8 Nov 7 12:33:26 iPad MyApp[3096] <Warning>: Debug - Background task 8 ended Nov 7 12:33:26 iPad MyApp[3096] <Warning>: Debug - Ending background task 0 Nov 7 12:33:26 iPad MyApp[3096] <Warning>: Debug - Background task 0 ended
我无法分辨双重通话何时发生,为什么。 所以问题是为什么被调用两次,有没有办法避免它?
编辑:
- (void) pauseDownloads { for (AFDownloadRequestOperation *operation in self.operationQueue.operations) { if(![operation isPaused]) { [operation pause]; } } }
你应该结束背景没有到期
UIApplication* app = [UIApplication sharedApplication]; bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ [self pauseDownloads]; NSLog(@"Debug - Ending background task %d",bgTask); [app endBackgroundTask:bgTask]; NSLog(@"Debug - Background task %d ended",bgTask); bgTask = UIBackgroundTaskInvalid; }]; NSLog(@"Debug - Starting background task %d",bgTask); [self initBackground]; NSLog(@"Debug - Ending background task %d without expiration",bgTask); [app endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid;
当应用程序进入前台,把这个平衡endBackgroundTask
调用 –
- (void)applicationWillEnterForeground:(UIApplication *)application { if (bgTask != UIBackgroundTaskInvalid) { NSLog(@"Debug - Ending background task %d without expiration (when applicationWillEnterForeground)",bgTask); [app endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; } // Also, to counter expiration handler pauseDownloads call, consider resuming the downloads here (or applicationDidBecomeActive app delegate). }
因为 – 过期处理程序块 {}在后台任务过期时执行(通常最多10分钟,但不能保证)。 我假设你的实际后台任务是[self initBackground];
,否则你应该把它放在块之外,并在endBackgroundTask
调用之前。
(另一个潜在的问题)
另外,我注意到你的暂停下载代码,看来你正在执行下载使用NSOperationQueue时,应用程序在后台。 在这种情况下,请确保在完成下载或到期处理程序执行之前,不会调用endBackgroundTask
。 换句话说,控制不会返回太早,这意味着您可能需要监视这些下载NSOperation(s)。
简短的回答是你的崩溃发生了,因为你创build了两个后台任务:7和8,但只有8。
有了这些知识,您应该应用Ashok的解决scheme,以确保您始终结束您创build的任何后台任务。