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

时间:2014-02-14 13:12:22

标签: ios iphone objective-c crash

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

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

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

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 部分看起来非常重要...... 当系统决定允许它被取消时,我是否应该以某种方式拦截我的应用程序暂停的可能性?还有其他解决这个问题的想法吗?

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

我的委托包含以下属性(该方法 - 由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秒内收到并解析数据(为了避免后台获取时间限制的问题)。

顺便说一句 - 代码USUALLY正常工作,但我真的不能让这种崩溃在生产中发生......

1 个答案:

答案 0 :(得分:0)

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

self.completionHandler = [completionHandler copy];