IOS 线程死锁详细介绍

2020-01-18 20:55:31丽君

iOS线程死锁

前言:

     在chat view的开发过程中,添加了“混合标签添加与显示”,app出现发送图片会出现卡死的情况,但过了大约30~40 second后会恢复正常。

问题分析:

     因为没有任何报错与提示,只能根据表面现象慢慢分析,经过多次测试与观察得出以下规律:

     (1)发送表情与文本不会发生该情况,只有发送图片才会发生app界面卡死的情况。(主线程阻塞,与大文件上传有关)
     (2)app卡死一定时间后会恢复正常,但时间不定,大约范围在30~40 second。(主线程解除阻塞,与系统某些机制有关)
     (3)当界面中有gif图时才会发生,界面中全是移动端本地图片是能顺利发送。(与gif下载有关)

     根据上述现象,可以总结为:主线程阻塞,过后因通信通信失败而阻塞解除。

     因为与gif图的下载有关,于是分析gif的下载实现,gif图的下载由以下代码实现。

        NSData *gifImageData = [NSDatadataWithContentsOfURL:model.imageRemoteURL];
        FLAnimatedImage *FLAImage = [FLAnimatedImageanimatedImageWithGIFData:gifImageData];

     其中,关于NSData的静态方法dataWithContentsOfURL的说明中有以下使用说明。

Important
Do not use this synchronous method to request network-based URLs. For network-based URLs, this method can block the current thread for tens of seconds on a slow network, resulting in a poor user experience, and in iOS, may cause your app to be terminated.

     这里说明了要尽量避免使用dataWithContentsOfURL从网络下载资源,因为它会阻塞当前线程,若下载的文件比较大而网络又不好就会带来很差的用户体验,对于iOS设备还可能引起app被迫终止。

  虽然只需要把dataWithContentsOfURL放置到别的线程中实现,又或者使用NSURLConnect、NSURLSession中的异步请求方法也能解决问题,但本质上引起这问题是因为调用dataWithContentsOfURL时网络环境差吗?

  明显不是,因为测试环境是模拟器,模拟器的cpu、网络通信是比真机要好的,只有GPU是不如真机。而且问题的出现规律是固定。

  但dataWithContentsOfURL已经解析了为什么主线程阻塞,那么现在需要解析为什么会阻塞那么长的时间。

     CPU分析结果:
     IOS,线程死锁,线程死锁详解,线程死锁实例