iOS Background Crash问题总结

一、background crash日志问题

      这部分日志一般是一些特殊场景下,系统强杀无法捕捉的 crash 信号,只能依赖apple系统自己的crash系统:第一种常用的通过Xcode -> Organizer查找日志,第二种通过手机设置->隐私→分析,查看日志;

       备注:手机设置→隐私→分析里的日志有很多其他知识

二、问题实例的 background crash问题

    1、现象: app进入后台约3分钟,再次打开app会重新从启动页启动,体验不好。

    2、前期优化:在收到内存警告信号BOOM后,清理所有缓存。但在并未占用过多内存+cpu的情况下依然如此。

   crash日志:

 

0x8badf00d

这个信号要记住是app主线程卡住时间过长,watchdog会强杀app,并生成一个带0x8badf00d的crash信号。

Background Task使用不当也会导致系统强杀的crash信号。

问题代码:

 

每个对 beginBackgroundTaskWithExpirationHandler:方法的调用,必须要相应的调用 endBackgroundTask:方法。这样,来告诉应用程序你已经执行完成了。 也就是说,我们向 iOS 要更多时间来完成一个任务,那么我们必须告诉 iOS 你什么时候能完成那个任务。

正确使用代码:

    __block UIBackgroundTaskIdentifier bgTask = [[UIApplication shareApllication] beginBackgroundTaskWithExpirationHandler:^{

          //标记指定的后台任务完成

         [applications endBackgroundTask:bgTask];

          //销毁后台任务标识符

         bgTask = UIBackgroundTaskInvalid;

    }];

问题其实就是endBackgroundTask时找任务ID失败,导致无法正常end。所以block中end时taskID一定要一一对应,尤其是可能会执行2遍的task。

 

另外,beginBackgroundTask在前台即可启动,不必等到applicationDidEnterBackground。

3、如何区分0x8badf00d是主线程卡死,还是backgroundTask leak?

线程崩溃日志下主线程的stack如上图。这个stack很常见,是主线程runloop处于idle状态的stack,在等待kernel的message。此时UI处于闲置状态,这时候系统强杀大多是backgroudTask leak。

三、其他后台crash

   1、0xbada5e47

     backgroundtask 过多+background ExpirationHandler任务执行时间过长(若干秒):

  2、0xdead10cc

   

    app被系统suspend时还存在任何访问db的操作,系统为考虑数据库文件的完整性,此时会被系统强杀。

官方文档解释:

The exception code 0xdead10cc indicates that an application has been terminated by iOS because it held on to a system resource (like the address book database) while running in the background.

例子:

App 在后台首先通过 PushKit 被唤醒,获得 30 秒的运行时间,在 30 秒即将结束的时候,收到新的 PushKit 通知,进而触发一些列流程,比如 sqlite 读写,而因为 30 秒后台时间已用完,系统会强行 suspend App 进程。

系统在 suspend 进程之前,会多做一道检查,如果 App 此时持有 sqlite db 文件的锁(比如正在进行写操作),而且所访问的 sqlite db 文件是位于 shared container 目录下,系统会强杀进程,并生成一个类似上面的 Crash Report。

系统为什么要这么做?很简单,如果 sqlite db 文件是位于 shared container,意味着该文件会同时被 App 和 Extension 访问,假设 App 的写操作在执行中途被 suspend 暂停,Extension 唤醒后也对同一个 db 文件执行写操作,那么当 App 被重新唤醒继续之前写操作时,写操作和 db 文件就会处于一个不可预知的状态,有可能造成写操作失败或者 db 文件损坏,所以系统选择强杀 App。

 

解决方案:进入后台后的db操作确保放在suspend之前,例如backgroundTask中,并简化所以后台任务的行为。

有这类隐患的场景,例如:backgroundTask中异步事件、VOIP的pushkit后台唤醒。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值