IOs7 应用程序在后台崩溃

2024-04-18

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

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

翻看其他问题 https://stackoverflow.com/questions/10319643/objective-c-proper-use-of-beginbackgroundtaskwithexpirationhandler我发现崩溃消息表明我没有正确结束任务,因此当其时间到期时,操作系统结束了它并使我的应用程序崩溃。

所以我添加了一些 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

我无法判断双重调用何时发生以及原因。所以问题是为什么任务被调用两次,有没有办法避免它?

Edit:

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

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

(另一个潜在问题)

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IOs7 应用程序在后台崩溃 的相关文章

随机推荐