KVO使用不当导致的崩溃

现象:对象被释放时崩溃

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

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

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

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就被释放了(就是想不到被释放对象有没有移除的观察者会崩溃)

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

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

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

时间: 2024-10-20 10:26:10

KVO使用不当导致的崩溃的相关文章

iOS之NSMutableDictionary导致程序崩溃:'NSInternalInconsistencyException'

使用NSMutableDictionary时,如果操作不当,有可能会引起程序崩溃.示例代码: NSString *result = @"{\"username\":\"aaa\",\"phone\":\"15666666666\",\"bankcount\":\"98765432112345678\"}"; NSData *data = [result dataUsi

在Ubuntu上,使用SWT嵌入AWT/SWING代码导致Eclipse崩溃问题

配置:Ubuntu 13.04 + Eclipse4.3 + JRE 7 现象:打开一个内嵌AWT/SWING代码的Eclipse 视图,Eclipse直接挂掉 原因:AWT/SWING和SWT都在访问GTK时都使用了锁去保护自己的线程.AWT使用的GTK的锁,但是SWT使用的自己的锁.在使用SWT访问AWT时,就会出错. 解决办法:在使用SWT访问AWT的代码中将以下代码:      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeel

Dispatcher.BeginInvoke()方法使用不当导致UI界面卡死的原因分析

原文:Dispatcher.BeginInvoke()方法使用不当导致UI界面卡死的原因分析 前段时间,公司同事开发了一个小工具,在工具执行过程中,UI界面一直处于卡死状态. 通过阅读代码发现,主要是由于Dispatcher.BeginInvoke()方法使用不当导致的. 本文将通过一个WPF模拟程序来演示一下界面卡死的现象,并通过修改代码来解决界面卡死的问题. 希望通过对本文的学习,大家能对Dispatcher.BeginInvoke()方法有一个新的认识. 文章开篇直接给出界面卡死的示例代码

viewDidLayoutSubviews在ios7上导致应用崩溃

在ios8中使用viewDidLayoutSubviews,应用正常运行,没有问题,但是应用在ios7上运行的时候,报错,导致应用崩溃,错误信息类似: Cannot find executable for CFBundle 0x78f8f220 </Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 7.1.simruntime/Contents/Resources/RuntimeRoot/System/Library/Accessibil

解决Qt中QTableWidget类方法setItem 时导致程序崩溃问题

在为一个音乐播放器增加功能时莫明奇妙的出现程序崩溃,定位到是由于QTableWidget 的setItem方法导致的,最终在此处找到了解决方式. 大致是说不能在setItem之前连接cellChanged 信号,把连接cellChanged信号的语句放置在一连串的setItem(在表格插入一行后调用的)之后就可以了. 解决Qt中QTableWidget类方法setItem 时导致程序崩溃问题

Qt学习之系列[9] – QCoreApplication:processEvents()可能会引起递归,导致栈溢出崩溃

api含义:QCoreApplication::processEvents() 将处理所有事件队列中的事件并返回给调用者. 问题描述: 当主线程在某个槽函数里正在执行processEvents时, 刚好有一个能响应此槽函数的信号发送过来了(肯定是其他线程发的信号),  这时就可能会发生可怕的递归, 导致栈溢出崩溃. 原因是processEvents,进入到无尽的递归中. 示例代码: bugThread.h #include <QThread> class BugThread : public

Win7下使用PB9可能导致的崩溃问题解决方案

在Win7环境下使用PB9进行程序开发,在打开Window或者DataWindow的时候,包括运行程序之后的退出,有可能导致程序崩溃而且开发环境直接退出,出现这样情况的原因是因为PB9所自带的核心软件包尚不足以支持Win7下的开发,为了弥补这个问题,Sybase在后来推出了PB9针对Win7系统下的操作补丁,使用此补丁可以解决以上的问题. 补丁下载地址: http://pan.baidu.com/s/1mg0wwPy

网站导致浏览器崩溃的原因总结(多款浏览器)

面试某公司的时候,面试官问到,导致浏览器崩溃的原因有哪些?愚辈不才,仅回答出了内存泄漏.其实在网页在装载的过程中,常常由于种种原因使浏览器的反映变的很慢,或造成浏览器失去响应,甚至会导致机器无法进行其他的操作. 对于访客,如果登录您网站,浏览器就立刻崩溃,我想这对谁都是无法容忍的,对此总结了网站导致浏览器崩溃的原因: 1. 内存泄漏 还是先谈下内存泄漏,网站由于内存泄漏的而照成崩溃有两种情况,服务器的崩溃和浏览器的崩溃.内存泄漏所造成的问题是显而易见的,它使得已分配的内存的引用就会丢失,只要系统

Win7下VC++6.0打开文件报错导致其崩溃的解决办法

原文:http://blog.csdn.net/wanghaihao_1/article/details/39005771 在Windows7下安装Visual C++ 6.0后,遇到一个致命的问题打开文件的时候出现异常而导致VC6崩溃. 如下图所示: 微软针对这个问题发布了一个补丁,原补丁是未编译的VC++6工程(FileTool),大家可以手动在VC++6.0环境下编译一下. 为了方便使用,我在这里还提供了一个已编译的版本FileTool.dll_已编译.zip 这里提供下载:FileToo