循环引用问题 -- dealloc方法不执行
dealloc不执行
如果一个类在释放过后,dealloc方法没有执行,那么就代表着这个类还被其他对象所引用,引用计数不为0,这样就造成了内存泄露
昨天其他业务线开发告知他所依赖的我这边的父类VC的-dealloc 方法不执行,叫我跟一下
于是我很快的想到-dealloc没执行,肯定是循环引用内存泄露之类的问题,于是打开instrument,复现着触发步骤,一个红点,两个红点;嘿,就是你了,结果查找call trees过后就蒙蔽了,报错是jsonmodel的实例方法有问题,难道是某个子类化的JsonModel对象引用了这个VC? 但是这个类有接近两千行,我怎么看?
于是小组大神出场,其在使用了一番instrument过后,发现确实这个VC在释放过后引用计数不为0,但是从各个内存的使用情况啊,调用堆栈啊并看不出错误是出现在哪里(他说instrument改版后不太会用了),在得知我的业务需求过后,于是叫我去用最笨的办法去解决-- 把所有改动屏蔽掉,然后逐个取消屏蔽,看内存泄露在哪一个方法里面
于是尝试,定位,尝试,定位
最终找到循环引用的地方:

在block外面是把self指针置为weak了的,但是进入block过后,却是仍然使用的是强self指针去调用的本类方法,这样一来,便造成了经典的循环引用的问题:
self ---> block block ---> self
于是VC里面就没办法释放掉,这就是造成VC的dealloc方法未能执行的原因
对于@weakify,@strongify的解释:
#define weakify(...) \\
autoreleasepool {} \\
metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
#define strongify(...) \\
try {} @finally {} \\
_Pragma("clang diagnostic push") \\
_Pragma("clang diagnostic ignored \\"-Wshadow\\"") \\
metamacro_foreach(rac_strongify_,, __VA_ARGS__) \\
_Pragma("clang diagnostic pop")
他们的作用主要是在block内部管理对self的引用:
@weakify(self); // 定义了一个__weak的self_weak_变量
[RACObserve(self, name) subscribeNext:^(NSString *name) {
@strongify(self); // 局域定义了一个__strong的self指针指向self_weak
self.outputLabel.text = name;
}];
这两个宏一定成对出现,先weak再strong.可以很好的管理Block内部对self的引用。 当然你如果是一个不爱用黄色宏的盆友的话,你可以用原生代码写出来
__weak typeof(self) weakSelf = self;
self.Button.rac_command = [[RACCommand alloc] initWithEnabled:textSig signalBlock:^RACSignal *(NSString * input) {
__strong typeof(weakSelf) strongSelf = weakSelf;
return nil;
}];
总结:
在使用instrument的过程中可能因为某些原因,检测不到具体的某个函数的内存泄露,这个时候就不能依赖instrument了(也可能是本渣不太懂怎么调,欢迎指正),这个时候就只能使用最笨的办法 --- 还原二分法来trick了
循环引用问题 -- dealloc方法不执行的更多相关文章
- JS中For循环中嵌套setTimeout()方法的执行顺序
在For循环中执行setTimeOut()方法的代码,执行顺序是怎样的呢? 代码如下 function time() { for(var i= 0;i<5;i++){ setTimeout(fu ...
- 某个 UIView的dealloc方法不执行
一,可能情况: 1> timer 没有清楚 2> 循环引用 3> block引用了实例变量. 二,查找到结果竟是 1> 没有使用 property 创建的属性,默认是强引用,会 ...
- NSTimer循环引用的几种解决方案
前言 在iOS中,NSTimer的使用是非常频繁的,但是NSTimer在使用中需要注意,避免循环引用的问题.之前经常这样写: - (void)setupTimer { self.timer = [NS ...
- Block循环引用问题(Objective-c)
造成循环引用的简单理解是:Block的拥有者在Block作用域内部又引用了自己,因此导致了Block的拥有者永远无法释放内存,就出现了循环引用的内存泄漏 示例代码 @interface ObjTest ...
- 使用gc、objgraph干掉python内存泄露与循环引用!
Python使用引用计数和垃圾回收来做内存管理,前面也写过一遍文章<Python内存优化>,介绍了在python中,如何profile内存使用情况,并做出相应的优化.本文介绍两个更致命的问 ...
- Objective-C:对象之间循环引用会造成死循环
对象之间的循环引用 两个对象A.B,有可能会出现一种特殊的情况:A中包含B的实例变量:B中又包含A的实例变量,如果两个实例变量都是强引用(A有B实例变量的所有权,B也有A的实例变量的所有 ...
- iOS中Block循环引用的问题
说到循环引用问题,想必大家都碰到过吧,比如在使用Block的时候,使用__weakSelf来代替self解决等,但是对于这个,还是有不少可以探索的点,下面我就来说下,希望对大家有所帮助. 是否所有的B ...
- Python对象的循环引用问题
目录 Python对象循环引用 循环引用垃圾回收算法 容器对象 生成容器对象 追踪容器对象 结束追踪容器对象 分代容器对象链表 何时执行循环引用垃圾回收 循环引用的垃圾回收 循环引用中的终结器 pyt ...
- 0c-41-ARC下循环引用问题
1.ARC下循环引入问题 一个人拥有一只狗,一只狗拥有一个主人. 当增加d.owner = p;时形成循环引用. 解决方法:一端用strong,一端用weak. 2.ARC下@property参数 A ...
随机推荐
- POJ1034 The dog task
题目来源:http://poj.org/problem?id=1034 题目大意: 一个猎人在遛狗.猎人的路径由一些给定的点指定.狗跟随着猎人,要与主人同时到达那些指定的点.在丛林里有一些有趣的地方, ...
- Phpstorm Git 操作
一.前提: 1.下载并安装好 Phpstorm 2.下载并安装好 Git 3.熟悉 Git 相关命令行操作 二.Git pull & commit(add): 下面简单说一下相关操作: Php ...
- python入门之paramiko模块
paramiko用于实现ssh远程连接服务器执行相关操作. paramiko与之依赖模块cryptography最好版本相同,不然可能执行程序会出错. 一.ssh连接服务器执行命令 import pa ...
- 【Java】在eclipse中使用gradle进行项目构建 入门篇
##Gradle的安装与配置- Gradle 是以 Groovy 语言为基础,面向Java应用为主,基于DSL(领域特定语言)语法的自动化构建工具. 系统环境变量中添加gradle 前往官网下载Com ...
- android 开发-ListView列表显示控件的实现
列表的显示需要三个元素: 1.ListVeiw 用来展示列表的View. 2.适配器 用来把数据映射到ListView上的中介. 3.数据 具体的将被映射的字符串,图片,或者基本组件. 根据列表 ...
- HDU 5501——The Highest Mark——————【贪心+dp】
The Highest Mark Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- orcale错题分析
删除同义词语法正确的是: Drop synonym sy nonym_name; 关于Oracle创建间隔分区后,正确的是: 使用partition(分区名)可以查看特定分区内存放的表记录 关于序列 ...
- C#数据库(MSSQL)帮助类
/// <summary> /// 数据库帮助类 /// <author>Devin</author> /// </summary> public se ...
- 多个activity之间的数据共享
Activity之间的数据共享问题起初一看并没有那么纠结,原因在于两点,一来两个Activity之间可以通过回传的方式进行数据的共享,而哪怕是多个Activity之间,也可以通过静态类进行数据的共享. ...
- Java并发(六):并发策略
通过多次优化实例来了解选择并发策略的正确姿势 通过模拟浏览器程序的渲染页面(Page-Rendering)功能,为了方便,假设HTML页面只会包含标签文本和图片以及URL; 第一个版本:串行加载页面元 ...