MRC下delegate 野指针问题
最近项目开发中,临时被调去修复一个页面返回时crash的问题。出现这个问题的原因也很巧合,正好服务地址在同事电脑上,也正巧网络请求响应时间狂慢!一个请求发出去回来的时间是40秒左右,要是在线上,肯定会让用户抓狂死!
当我打开项目的时候,点击页面返回时,发现网络请求依然在请求中,第一感觉就是内存管理上出错。在全局断点中定位到出问题的点上,竟然是delegate回调的地方出现了问题!
if (self.delegate && [self.delegate respondsToSelector:@selector(test:)]) {
        [self.delegate test:nil];
    }
这段代码在iOS开发中随处可见,而且其正确性在现在版本中毋庸置疑。一开始我并没有以为是delegate这边出错,因为我查了下property的确是assign。在ViewController里面又查了下相关内存操作,在dealloc中发现一个严重问题,我的VC都销毁了,里面对象竟然木有销毁,这的确很诡异。由于项目中结构有点奇葩,属于MVC重度用户!未销毁的对象就是我们所谓的负责业务逻辑的对象,在对其引用的地方只有网络请求的地方,在调用函数参数中delegate设置为self。在iOS开发中,我们会将网络请求放入到一个队列中,在网络请求成功后,在队列中取出网络请求相关信息,并移除此请求。由于在将网络请求加入到队列中对传进来的self进行了强引用,所以这个可以解释为什么我们业务处理对象引用计数为什么会大于1,而导致不能销毁。虽然这在设计上来说的确存在不合理性,我只需一个delegate而不需要对调用对象进行强引用。但仔细想想这个不至于导致程序挂掉,虽然我对你调用对象进行了引用计数加1,大不了内存迟点释放,走遍回调,我实际调用的VC已经是nil了所以也不会调用。
就是这个我认为VC一定是nil,毕竟我看到它在内存中销毁了。将Xcode debug中zombie objects勾上,重新调试,结果控制台中打印出 message sent to deallocated instance 0x90a3900,彻底改变了我的世界观!delegate不是nil。。。。可是我的delegate的确是assign啊!这是为什么呢?最根本的原因是将ARC中weak和MRC中的assign给混为一谈了。。。。
weak和assign对传入的对象不会改变引用计数的变化。所以发现我们的delegate,在MRC中是assign,在ARC中是weak。但是这两点有什么区别呢?两者都可以保证对传入的对象不会改变引用计数,但是weak对象必须是oc对象。weak比assign强大的地方就是在指向的对象销毁时,所有指向该对象的weak指针都会置为nil。这样我们就可以写出如此简洁的判断if (self.delegate && [self.delegate respondsToSelector:@selector(test:)])。而在MRC中,如果直接写这样的代码,如果调用者在对象销毁时未将delegate置为nil,delegate将变成野指针,而导致程序挂掉。这也是为什么苹果官方推荐大家是用ARC,ARC在很多地方都可以保证程序的健壮性。
MRC下delegate 野指针问题的更多相关文章
- C程序中可怕的野指针
		一.疑问点指针是C语言一个很强大的功能,同时也是很容易让人犯错的一个功能,用错了指针,轻者只是报个错,重者可能整个系统都崩溃了.下面是大家在编写C程序时,经常遇到的一种错误的使用方法,也许在你的学习和 ... 
- C程序疑问解答 ——可怕的野指针
		本篇为原创,禁止任何形式的他用! 一.疑问点 指针是C语言一个很强大的功能,同时也是很容易让人犯错的一个功能,用错了指针,轻者只是报个错,重者可能整个系统都崩溃了.下面是大家在编写C程 ... 
- 七.OC基础加强--1.内存管理  2.野指针,内存泄露  3.set方法的内存管理  4.@property参数  5.@class和循环retain的使用  6.NSString的内存管理
		1,内存管理简单介绍 1,为什么要有内存管理? malloc selloc dealloc```需要回头复习 一般的内存 4s 是512m内存:6 是1024m内存: 当内存过大时,会耗尽内存.出现程 ... 
- OC-引用计数器,内存管理,野指针
		总结 全局断点 →-->+-->Add Exception Breakpoint 开启僵尸监听 打开Edit scheme -->Diagnostics-->Enable Zo ... 
- iOS为真机调试增加scribble来定位野指针
		尽管在ARC中,野指针出现的频率已经大大降低了,但是仍然会有野指针困扰着我们. 在模拟器调试中,我们可以开启scribble或者zombieObject来将已经释放的内存填充无意义的内容,能够将一些非 ... 
- NULL指针、零指针、野指针
		1.1.空指针 如果 p 是一个指针变量,则 p = 0; p = 0L; p = '\0'; p = 3 - 3; p = 0 * 17;p=(void*)0; 中的任何一种赋值操作之后, p 都成 ... 
- 黑马程序员-nil Nil NULL NSNull   野指针和空指针
		空指针1.空指针指不含有任何内存地址的指针.在没有具体初始化之前,其被符值为0Dog * dog = nil;Dog * dog = NULL;都为空指针2.野指针指指向的内存为垃圾内存,导致其值不确 ... 
- iOS--检测野指针
		定位野指针除了使用Malloc Scribble(内存涂鸦)外,还可以使用僵尸对象.所谓的僵尸对象,就是将被释放的对象标记为僵尸,系统不会回收这些对象的内存,并让这些内存无法被重用,因而也就不会被覆写 ... 
- 使用AFNetworking时, 控制器点击返回销毁了, 但还是会执行请求成功或失败的block, 导致野指针异常
		原本我以为是我程序框架有问题...后来才知道, 无知真可怕... __unsafe_unretained __block typeof(self) weakSelf = self; AFHTTPSes ... 
随机推荐
- IfcRelDefinesByProperties  IfcPropertySetDefinitionSelect  IfcPropertySetDefinition IfcPropertySetDefinitionSet
			private void updateObject(IfcObject ifcObject, PropertyNode root) { /* if(ifcObject.getClassName().t ... 
- React vs. Angular vs. Vue
			原文连接 历史 React是一个用于构建Web应用程序UI组件的JavaScript库. React由Facebook维护,许多领先的科技品牌在其开发环境中使用React. React被Faceboo ... 
- PAT 甲级 1060 Are They Equal (25 分)(科学计数法,接连做了2天,考虑要全面,坑点多,真麻烦)
			1060 Are They Equal (25 分) If a machine can save only 3 significant digits, the float numbers 1230 ... 
- C++ - 第一个程序
			代码: #include <iostream> using namespace std; int main() { cout << "hello!" < ... 
- 前端表格插件datatables
			下载datatables datatables官网:https://www.datatables.net/ datatables下载地址:https://www.datatables.net/down ... 
- 【miscellaneous】GStreamer下的音视频播放
			Gst-launch命令: gst-launch filesrc location=*.* ! demux name=demux demux.video_00 ! queue ! decoder ! ... 
- uwp,右键浮出获取DataContext(数据上下文)
			列表视图类控件,如ListView/GridView,有时项目需要按下右键浮出选项,来获取Item的DataContext. 下面的示例代码,事先我已经有了一个自定义类Video,并且已经绑定了数据源 ... 
- EasyUI 对话框弹出文件输入框
			目前用的EasyUI的dialog,要实现弹出文件输入框(或者其他输入框和对话框),我的实现方案是,首先写一个close的div,然后里面就是样式和输入框的一些代码和一个确定按钮,然后页面上一个按钮, ... 
- 利用Python进行数据分析_Numpy_基础_3
			通用函数:快速的元素级数组函数 通用函数,是指对数组中的数据执行元素级运算的函数:接受一个或多个标量值,并产生一个或多个标量值. sqrt 求平方根 np.sqrt(arr) exp 计算各元素指数 ... 
- cliff
			let me tell you,buddy. there's a faster gun. cming over yonder,when tomorrow comes. 
