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

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

场景

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

流程

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

问题

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

其它问题

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、深复制和浅复制的区别? 1、浅复制:只是复制了指向对象的指针,即两个指针指向同一块内存单元!而不复制指向对象的...
    iOS_Alex阅读 1,423评论 1 27
  • 218.241.181.202 wxhl60 123456 192.168.10.253 wxhl66 wxhl6...
    CYC666阅读 1,420评论 0 6
  • 1.自定义控件 a.继承某个控件 b.重写initWithFrame方法可以设置一些它的属性 c.在layouts...
    圍繞的城阅读 3,454评论 2 4
  • 学习Android的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Android学习交流...
    kingZXY2009阅读 355评论 0 0
  • 焦虑是一种很特别的情感——一种一定会被觉察到的情感。也就是说,也许你抑郁,但是你不知道你的这种负面情绪是什么;但只...
    斯坦威阅读 309评论 0 0