【问题标题】:IOs7 app crashing when in backgroundIOS7应用程序在后台崩溃
【发布时间】:2013-11-07 15:04:21
【问题描述】:

我的应用有时会在后台崩溃并显示以下崩溃日志:

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 
    )}

查看其他questions,我发现崩溃消息表明我没有正确结束任务,所以当时间到期时,操作系统结束了它并崩溃了我的应用程序。

所以我添加了一些 NSLog:

- (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];

    }

}

发现任务在crash的时候被调用了两次:

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];
        }
    }
}

【问题讨论】:

  • 你能发布 pauseDownloads 方法吗?
  • 当然,我编辑了问题
  • 检查你的initBackground方法,下载完成后结束后台任务。在 iOS 7 中,后台任务最长为 3 分钟,在 iOS 6 中约为 10 分钟。

标签: ios crash ios7


【解决方案1】:

你应该在没有过期的情况下结束背景..

    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;

当app进入前台时,把这个平衡endBackgroundTask call -

- (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).
}

因为 - 过期处理程序block {} 在后台任务过期时执行(通常最多 10 分钟,但不保证)。我假设你的实际后台任务是[self initBackground];,否则你应该把它放在块之外和endBackgroundTask调用之前。

(另一个潜在问题)

另外,我现在注意到您的 pauseDownloads 代码,当应用程序进入后台时,您似乎正在使用 NSOperationQueue 执行下载。在这种情况下,请确保在您完成下载或执行到期处理程序之前不会调用endBackgroundTask。换句话说,控件不会过早返回,这意味着您可能需要监视这些下载的 NSOperation(s)。

【讨论】:

  • 实际上这段代码不是我写的,我被指派修复这个崩溃,写它的人不再在这里工作,所以我不太确定他的意图,但是我相信任务并没有结束以保持下载尽可能长时间地运行
  • 好的,但这是一个需要解决的有趣问题。我相信你至少需要几个小时来理解和修复它,而不仅仅是几分钟。我建议您尝试在这些 NSLogs 中添加一些时间戳[NSDate date],以帮助您调试和理解。注意 - AFAIK,如果 NSOperationQueue 没有限制它,每个 NSOperation 都被派生在一个单独的线程中执行。当您有空时,您可以阅读此链接 - stackoverflow.com/questions/19569244/…
  • 我会试试的,谢谢,关于任务被调用两次有什么想法吗?
  • 我刚注意到在您的日志中调试时间戳一开始。做一件事,在applicationWillEnterForeground 委托方法中放置一个平衡的endBackgroundTask 调用。看起来只有当应用程序经常从前台切换到后台时才会发生这种崩溃!!??
  • 是的,崩溃就是这样发生的,当应用程序经常从前台切换到后台时,我尝试了您的建议,我需要运行更多测试,但似乎已经解决了这个问题,非常感谢
【解决方案2】:

简短的回答是,您的崩溃之所以发生,是因为您创建了两个后台任务:7 和 8,但仅在 8 结束。

有了这些知识,您应该应用 Ashok 的解决方案来确保您始终结束您创建的任何后台任务。

【讨论】:

    猜你喜欢
    • 2013-11-30
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 2013-11-04
    • 2013-11-17
    • 1970-01-01
    相关资源
    最近更新 更多