码迷,mamicode.com
首页 > 其他好文 > 详细

KVO使用不当导致的崩溃

时间:2017-08-21 18:51:39      阅读:1254      评论:0      收藏:0      [点我收藏+]

标签:retain   方法   操作   两种   oca   bre   ons   看到了   情况   

现象:对象被释放时崩溃

原因:对象有未移除的观察者

 

记录一下自己解决问题的过程,反思自己在解决问题过程中是不是方法得当:

今天遇到一个莫名崩溃——属性被赋值的时候崩溃。像这样

技术分享

 

console没有任何提示。

楼主开始只注意到1、2,着手调查breakPoint 1.1是啥。走了一些弯路。其实真正的通关提示语在3。

可以从3中看到这样一个信息NSKVODeallocate,这就基本确定是kvo使用不当造成的。

kvo造成的崩溃我只遇到过两种,一种是释放对象时对象上有未移除的观察者,第二种是移除从未注册过或已移除过的观察者。

说到这,聪明的你是不是想到了什么

属性赋值意味着新属性对象的retain count+1,老属性对象的retain count-1,所以老属性对象有被释放的可能

容易联想到第一种崩溃情况(当然,这都是马后炮,事实上了楼主并没有想到这里。楼主只是去搜了“属性赋值 崩溃 iOS”??)

好了吧,事情就是这么个事情,干货没有了,接下来我要继续讲我的探险历程了

当时我的内心是这样告诉我的:dealloc + kvo = 往dealloc的对象里面发消息造成的崩溃?

于是我看了崩溃时的内存图

技术分享

 

箭头指的是看内存图的地方(xcode8)

红框中就是崩溃发生时的老属性(老self.dataSource)

看到了有被释放的对象,更加验证了我“是给被释放的对象发kvo相关消息导致崩溃的” 的观念。(发现楼主喜欢靠直觉去找问题。实际上这道题不考直觉,仔细分析,或许会更快。因为一些结论失之毫厘差之千里)

被释放的是老属性,崩溃应该在上面老属性移除观察者时崩溃,但是楼主想,也许这是编译器定位不准呢?然后楼主带着疑问进入下一项

然后楼主想苹果是在对象被dealloc的时候自动给观察者发消息了?还是我自己在setter、getter里做了什么?(现在看起来挺糊涂的。)

验证了我确实没在setter、getter里做啥,楼主找了一段代码来检测进入setData:Delegate:At方法时是否self.dataSource已经被释放了

结果是,没有

刚进入setData:Delegate:At方法时self.dataSource还是正常的,而后崩溃时,self.dataSource就被释放了(就是想不到被释放对象有没有移除的观察者会崩溃)

然后楼主想,这肯定是系统有啥我不知道的隐形操作或规则,毫无头绪的我打算战略性撤退

放弃这个问题后还是一直想着,然后最开始提到的情况一进入我的脑海,然后楼主想到了以前留下的一个坑

火速更改,然后测试,不崩溃了!!!

KVO使用不当导致的崩溃

标签:retain   方法   操作   两种   oca   bre   ons   看到了   情况   

原文地址:http://www.cnblogs.com/lu-diary/p/7405955.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!