0

在 ping 服务器之前,我使用以下代码为我的应用程序添加了后台进程支持:

UIApplication *app = [UIApplication sharedApplication];
        bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
            [app endBackgroundTask:bgTask];
            bgTask = UIBackgroundTaskInvalid;
        }];
        if (!connection) {
            connection = [[NSURLConnection alloc] init];
        }
        (void)[connection initWithRequest:originalRequest delegate:self];

由于这段代码,如果我将应用程序保持在后台模式超过 10 分钟,它就会崩溃。根据我的理解,我不应该让任务在后台连续运行,我应该为每个任务设置一些时间间隔。但我不知道如何设置杀死他们的时间间隔。

请建议我一些步骤来解决这个问题。

4

1 回答 1

1

这里有几个重要的点,其中许多已经在评论中介绍过。

首先,你拥有的时间是未知的。有经验值(iOS 7 前 10 分钟/iOS 7 前 3 分钟),但不能保证这些值。特别是,如果您从睡眠中醒来做工作(例如地理围栏警报),您可能无法获得全部时间,您可能只能获得上次剩余的时间。您可以采取一些特定的操作来重置时间(例如,使用 GPS 获取您的位置可能会在某些 iOS 版本中重置计时器)。

其次,你被杀不是因为你还在工作,你被杀是因为你告诉操作系统你还在工作。操作系统不关心您的网络传输,它关心您的 beginBackgroundTaskWithExpirationHandler。

您可以从崩溃报告中验证这一点,该报告将显示“有超出允许时间的活动断言”

这有三个可能的原因。
1) 操作系统调用了您的完成处理程序,但您没有及时调用 endBackgroundTask。调用后台处理程序时您没有太多时间,但我怀疑这是问题所在,您的代码非常紧凑。

2) 操作系统调用了您的完成处理程序,但您根本没有调用 endBackgroundTask。我继承了执行此操作的代码,正常原因是代码不可重入,并且被调用了两次。bgtask 更新为第二个值,因此当完成处理程序触发时, bgtask 会为一个任务结束两次,而不会为另一个结束。同样,我认为您很安全,这通常是成员变量的问题,在您的情况下, bgtask 应该由块复制。

3)操作系统没有调用你的后台处理程序(不太可能,但我对 iOS 7 有一些可能毫无根据的怀疑)。

下一个可能不是真正的后台执行问题是您并没有真正崩溃。在与 Xcode 断开连接的情况下运行您的应用程序,看看它是否会生成崩溃报告。如果没有,您可能只是由于内存压力而被弹出。如果这真的是一个太长的后台问题,你会看到异常代码是 0x0badfood。糟糕的食物是让看门狗计时器生气的原因。

我认为后台进程曾经在它们被悄悄弹出时从后台应用程序中删除,但现在操作系统用屏幕截图替换它们并在用户将它们带到前台时重新启动它们。

于 2013-10-28T09:50:58.273 回答