我正在努力为我的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正常工作,但我真的不能让这种崩溃在生产中发生......
答案 0 :(得分:0)
您现在可能已经解决了问题,但我们通过复制completionHandler修复了一个带背景提取的问题(如果您将其保存为正在执行的属性)。例如:
self.completionHandler = [completionHandler copy];