多线程写读写字典引起的crash

2017-11-04  本文已影响45人  Bearger

一个偶现的Bug,并且只在iOS11发布后才出来的。

场景

场景比较简单:使用一个单例做缓存。单例中加了一个可变字典,用于缓存已经加载过的图片。

流程

根据图片的名称从字典中查找图片对象,当找不到对象的时候就创建一个新的UIImage对象,并保存到字典中。找到对象就直接取现在有的缓存UIImage。

问题

多线程时,NSMutableDictionary取对象不是元子操作,所以,多个线程请求同一个图片对象时都得到nil。然后就都跑去创建UIImage对象,并都试图保存。创建UIImage对象时,使用imageNamed方法,系统做了优化,进行缓存处理了。
NSMutableDictionary中添加相同的key的时候,会被原来的对象移除。第一个线程保存结束后,此时如果第二个线程试图添加的对象正是第一个线程刚放进去的对象,会出现这样的流程:判断字典中是否有key时成立,然后将对象移除,内存回收,再往字典里写对象时,就等于设置了一个野指针对象。

其它问题

虽然听说使用imageNamed,系统对自己做缓存,可之前试过,对于同一张图片,所创建的新UIImage对象的内存地址都不一样~所以,=。=

上一篇下一篇

猜你喜欢

热点阅读