最近在项目中又遇到了一个卡死问题,表现是这样的: 用户在首页进入摄像头页面后退出来,然后APP退到后台30s后回到前台,这时候再点击摄像头页面有很大概率卡死长达1分钟。
从表现来看,跟之前的postNotification卡死问题有些像,但不同的是,卡了1分钟之后又恢复的,因此感觉不是死锁,而且从日志的打印情况来看,也没有检测到主线程卡死。
于是上Time Profile ,可以看到1分钟的时候开始进入severe hang,
点击Thread查看线程情况,发现heavist Stack trace 在SDWebImageCache这里
然后尝试分析打断点,发现在卡死后,主线程的调用栈如下:
点击进入一看,发现是SDWebImage里面调用了dispatch_sync,而调用栈最下方的代码是在ViewDidload方法中,因此瞬间明白问题所在,这是主线程在等待io线程清理缓存导致卡死。
这里必须要吐槽一下之前的人了,在读取图片缓存的时候居然没有考虑到主线程调用的问题,正常来说即便不卡死也会卡顿一下,因此必须要放在子线程处理。
解决方案也很简单:
- 在读取SDWebImage的时候另外启动一个线程去读取。
- 使用SDWebImage的异步方法去读取图片缓存。
这个问题抛出来主要是提醒各位,写代码时一定要注意性能,有明显的读写缓存和网络数据的地方一定要放在子线程去做,千万别为图方便导致程序出现各种问题。