具有后台获取功能的 iOS 应用程序在后台崩溃,异常 0xbad5bbad

标签 ios iphone objective-c crash

我正在为我的 iOS 应用程序添加后台获取功能。它使用 Core Data 作为唯一存储,我正在执行的 fetch 将一些信息(一种“获取通知”)添加到数据库中。

在实现所有内容并使用 Xcode 调试菜单中的模拟提取成功对其进行测试后,我决定进行一些现场实验——我设置了 UIApplicationBackgroundFetchIntervalMinimum,启动了应用程序,将其发送到后台并将我的 5s 单独放置了几个小时。

唤醒手机后,我将应用程序切换回前台,并注意到它已经删除了我登录的用户帐户 - 唯一可能发生的方法是清除核心数据的内容,这显然是一个非常关键的问题。在组织者的设备日志 Pane 中,我发现了以下崩溃日志:

Incident Identifier: FE34EA01-4DA0-4315-DDA8-33DC8CD0CAA1
CrashReporter Key:   37018631ac51170b5781f4d9fcd950db64f89180
Hardware Model:      iPhone6,2
OS Version:          iPhone OS 7.0.5 (11B601)
Kernel version:      Darwin Kernel Version 14.0.0: Fri Sep 27 23:08:32 PDT 2013; root:xnu-2423.3.12~1/RELEASE_ARM64_S5L8960X
Date:                2014-02-10 13:38:11 +0100
Exception Code:      0xbad5bbad
Reason:              my.apps.bundle should be bgContentFetching but he is task suspended instead

Thermal data unavailable

Frontmost process PID:    16
Jetsam Level:              0
Free Pages:            15483
Active Pages:         107037
Inactive Pages:        51702
Purgeable Pages:        4459
Wired Pages:           40181
Speculative Pages:      4166
Throttled Pages:           0
File-backed Pages:     82649
Compressions:         106865
Decompressions:        11520
Compressor Size:       36896
Busy Buffer Count:         0
Pages Wanted:              0
Pages Reclaimed:           0

Process 0 info:
    resident memory bytes:  935444480
    page faults:               21741
    page-ins:                      1
    copy-on-write faults:          0
    times throttled:              65
    times did throttle:           37
    user   time in task:       42962.479797 seconds
    system time in task:           0.000000 seconds

Process 0 kernel_task threads:
thread 0x1 TH_WAIT|TH_UNINT 0xffffff80006775cc
    thread priority:               92
    Base thread priority:          92
    thread sched flags:     none
    kernel cont: 0xffffff80003442b4
    user   time in thread:     1.300313 seconds
    system time in thread:     0.000000 seconds
thread 0x2 TH_RUN|TH_IDLE 0
    thread priority:                0
    Base thread priority:           0
    thread sched flags:     none
    kernel cont: 0xffffff80002f7f4c
    user   time in thread: 20862.364775 seconds
    system time in thread:     0.000000 seconds
thread 0x3 TH_WAIT|TH_UNINT 0xffffff80002f3d2c
    thread priority:               95
    Base thread priority:          95
    thread sched flags:     none
    kernel cont: 0xffffff80002f3d2c
    user   time in thread:     3.103439 seconds
    system time in thread:     0.000000 seconds etc . . .

现在 0xbad5bbad 部分看起来很关键......
当系统决定允许它获取时,我是否应该以某种方式拦截我的应用程序被挂起的这种可能性?解决这个问题的任何其他想法?

更新 - 添加了后台获取代码:

我的委托(delegate)包含以下属性(该方法 - 由 iOS 开发人员建议 - 在几个正常工作的应用程序中使用):
@property (nonatomic, copy) void (^completionHandler)(UIBackgroundFetchResult fetchResult);

获取代码:
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(alertFinished:) name:kNotification_Alerts_Method object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(alertFailed:) name:kNotification_Alerts_Method_Fail object:nil];

    [[AlertManager sharedInstance] updateItems];

    self.completionHandler = completionHandler;

}

-(void)alertFinished:(NSNotification *)notification
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kNotification_Alerts_Method object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kNotification_Alerts_Method_Fail object:nil];

    NSArray *alerts = [[AlertManager sharedInstance] getUnreadAlerts];

    if([alerts count] != 0)
    {
        for(Alert *alert in alerts)
        {
            //scheduling local notifications basing on the fetched alerts
        }

        if(self.completionHandler)
        {
            self.completionHandler(UIBackgroundFetchResultNewData);
        }
    }
    else
    {
        if(self.completionHandler)
        {
            self.completionHandler(UIBackgroundFetchResultNoData);
        }
    }
}

-(void)alertFailed:(NSNotification *)notification
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kNotification_Alerts_Method object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kNotification_Alerts_Method_Fail object:nil];

    if(self.completionHandler)
    {
        self.completionHandler(UIBackgroundFetchResultFailed);
    }
}

AlertManager 配置为报告失败,除非在 15 秒内接收并解析数据(以避免后台获取时间限制的问题)。

顺便说一句 - 代码通常可以正常工作,但我不能真正允许这样的崩溃在生产中发生......

最佳答案

您现在可能已经解决了您的问题,但我们通过复制 completionHandler 解决了后台获取的一个问题(如果您正在将其保存为属性)。例如:

self.completionHandler = [completionHandler copy];

关于具有后台获取功能的 iOS 应用程序在后台崩溃,异常 0xbad5bbad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21780381/

相关文章:

iphone - PhoneGap 和 Appcelerator 在本地和远程存储数据?

ios - 在 UITextView 中禁用文本选择

ios - UITableView 中的 UITextField 与 DatePicker 的 InputView

objective-c - 在 ObjC 中格式化非常大的十进制数字的意外行为

iphone - 有没有办法让 Round Rect 按钮拍摄完全相同大小的图像?

ios - Game Center 排行榜沙箱中只显示一个结果 - 正常吗?

ios - 这段代码有什么问题? Swift 选项

ios - UICollectionViewCell 的minimumInteritemSpacingForSectionAtIndex 不正确

iphone - 如何在 storyBoard 中添加 navigationController Controller

iphone - 针对 iOS 3 和 iOS 4 启用了 locationServices