在后台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的任何后台任务。