最近项目开发中,临时被调去修复一个页面返回时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 野指针问题的更多相关文章

  1. C程序中可怕的野指针

    一.疑问点指针是C语言一个很强大的功能,同时也是很容易让人犯错的一个功能,用错了指针,轻者只是报个错,重者可能整个系统都崩溃了.下面是大家在编写C程序时,经常遇到的一种错误的使用方法,也许在你的学习和 ...

  2. C程序疑问解答 ——可怕的野指针

    本篇为原创,禁止任何形式的他用! 一.疑问点         指针是C语言一个很强大的功能,同时也是很容易让人犯错的一个功能,用错了指针,轻者只是报个错,重者可能整个系统都崩溃了.下面是大家在编写C程 ...

  3. 七.OC基础加强--1.内存管理 2.野指针,内存泄露 3.set方法的内存管理 4.@property参数 5.@class和循环retain的使用 6.NSString的内存管理

    1,内存管理简单介绍 1,为什么要有内存管理? malloc selloc dealloc```需要回头复习 一般的内存 4s 是512m内存:6 是1024m内存: 当内存过大时,会耗尽内存.出现程 ...

  4. OC-引用计数器,内存管理,野指针

    总结 全局断点 →-->+-->Add Exception Breakpoint 开启僵尸监听 打开Edit scheme -->Diagnostics-->Enable Zo ...

  5. iOS为真机调试增加scribble来定位野指针

    尽管在ARC中,野指针出现的频率已经大大降低了,但是仍然会有野指针困扰着我们. 在模拟器调试中,我们可以开启scribble或者zombieObject来将已经释放的内存填充无意义的内容,能够将一些非 ...

  6. NULL指针、零指针、野指针

    1.1.空指针 如果 p 是一个指针变量,则 p = 0; p = 0L; p = '\0'; p = 3 - 3; p = 0 * 17;p=(void*)0; 中的任何一种赋值操作之后, p 都成 ...

  7. 黑马程序员-nil Nil NULL NSNull 野指针和空指针

    空指针1.空指针指不含有任何内存地址的指针.在没有具体初始化之前,其被符值为0Dog * dog = nil;Dog * dog = NULL;都为空指针2.野指针指指向的内存为垃圾内存,导致其值不确 ...

  8. iOS--检测野指针

    定位野指针除了使用Malloc Scribble(内存涂鸦)外,还可以使用僵尸对象.所谓的僵尸对象,就是将被释放的对象标记为僵尸,系统不会回收这些对象的内存,并让这些内存无法被重用,因而也就不会被覆写 ...

  9. 使用AFNetworking时, 控制器点击返回销毁了, 但还是会执行请求成功或失败的block, 导致野指针异常

    原本我以为是我程序框架有问题...后来才知道, 无知真可怕... __unsafe_unretained __block typeof(self) weakSelf = self; AFHTTPSes ...

随机推荐

  1. 阶段5 3.微服务项目【学成在线】_day07 课程管理实战_03-新增课程-课程分类查询

    2 新增课程 2.1 需求分析 用户操作流程如下: 1.用户进入“我的课程”页面,点击“新增课程”,进入新增课程页面 2.填写课程信息,选择课程分类.课程等级.学习模式等. 3.信息填写完毕,点击“提 ...

  2. 用python查看文件是否存在的三种方式

    目录 1.使用os模块 判断文件是否可做读写操作 2.使用Try语句 3. 使用pathlib模块 正文 通常在读写文件之前,需要判断文件或目录是否存在,不然某些处理方法可能会使程序出错.所以最好在做 ...

  3. jQuery学习四——效果

    1.显示,隐藏: <!DOCTYPE html> <html> <head> <title>jquery事件</title> </he ...

  4. laravel原生sql

    转自:https://www.cnblogs.com/zouzhe0/p/6307077.html DB::insert(, ']); $user = DB::]); //我们还 可以看到在执行查询的 ...

  5. Spring Cloud(7.1):安装Kafka和Redis

    Kafka安装 (1)从官方(http://kafka.apache.org/downloads)下载安装包.kafka安装包和一般安装包的命名方式不一样,我们看一个kafka包命名:kafka_2. ...

  6. jQuery BlockUI Plugin Demo 4(Element Blocking Examples)

    Element Blocking Examples This page demonstrates how to block selected elements on the page rather t ...

  7. C# 后台POST和GET 获取数据

    C# 后台POST和GET 获取数据 , data.Length);     newStream.Close();     HttpWebResponse myResponse = (HttpWebR ...

  8. CSS基础(html+css基础)

    css: CSS全称为“层叠样式表 (Cascading Style Sheets)”,它主要是用于定义HTML内容在浏览器内的显示样式,如文字大小.颜色.字体加粗等. 1.CSS代码语法: css ...

  9. git 创建标签推送远程分支

    目录 git 创建标签推送远程分支 查看tag 创建tag 推送标签到远程仓库 删除tag git 创建标签推送远程分支 标签概念: tag, 对于迭代频繁的项目. 每一个标签可以理解为一个版本. 创 ...

  10. 当微信小程序遇到AR(一)

    当微信小程序遇到AR,会擦出怎么样的火花?期待与激动...... 通过该教程,可以从基础开始打造一个微信小程序的AR框架,所有代码开源,提供大家学习. 本课程需要一定的基础:微信开发者工具,JavaS ...