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方法不执行的更多相关文章

  1. JS中For循环中嵌套setTimeout()方法的执行顺序

    在For循环中执行setTimeOut()方法的代码,执行顺序是怎样的呢? 代码如下 function time() { for(var i= 0;i<5;i++){ setTimeout(fu ...

  2. 某个 UIView的dealloc方法不执行

    一,可能情况: 1> timer 没有清楚 2> 循环引用 3> block引用了实例变量. 二,查找到结果竟是 1> 没有使用 property 创建的属性,默认是强引用,会 ...

  3. NSTimer循环引用的几种解决方案

    前言 在iOS中,NSTimer的使用是非常频繁的,但是NSTimer在使用中需要注意,避免循环引用的问题.之前经常这样写: - (void)setupTimer { self.timer = [NS ...

  4. Block循环引用问题(Objective-c)

    造成循环引用的简单理解是:Block的拥有者在Block作用域内部又引用了自己,因此导致了Block的拥有者永远无法释放内存,就出现了循环引用的内存泄漏 示例代码 @interface ObjTest ...

  5. 使用gc、objgraph干掉python内存泄露与循环引用!

    Python使用引用计数和垃圾回收来做内存管理,前面也写过一遍文章<Python内存优化>,介绍了在python中,如何profile内存使用情况,并做出相应的优化.本文介绍两个更致命的问 ...

  6. Objective-C:对象之间循环引用会造成死循环

    对象之间的循环引用        两个对象A.B,有可能会出现一种特殊的情况:A中包含B的实例变量:B中又包含A的实例变量,如果两个实例变量都是强引用(A有B实例变量的所有权,B也有A的实例变量的所有 ...

  7. iOS中Block循环引用的问题

    说到循环引用问题,想必大家都碰到过吧,比如在使用Block的时候,使用__weakSelf来代替self解决等,但是对于这个,还是有不少可以探索的点,下面我就来说下,希望对大家有所帮助. 是否所有的B ...

  8. Python对象的循环引用问题

    目录 Python对象循环引用 循环引用垃圾回收算法 容器对象 生成容器对象 追踪容器对象 结束追踪容器对象 分代容器对象链表 何时执行循环引用垃圾回收 循环引用的垃圾回收 循环引用中的终结器 pyt ...

  9. 0c-41-ARC下循环引用问题

    1.ARC下循环引入问题 一个人拥有一只狗,一只狗拥有一个主人. 当增加d.owner = p;时形成循环引用. 解决方法:一端用strong,一端用weak. 2.ARC下@property参数 A ...

随机推荐

  1. POJ1034 The dog task

    题目来源:http://poj.org/problem?id=1034 题目大意: 一个猎人在遛狗.猎人的路径由一些给定的点指定.狗跟随着猎人,要与主人同时到达那些指定的点.在丛林里有一些有趣的地方, ...

  2. Phpstorm Git 操作

    一.前提: 1.下载并安装好 Phpstorm 2.下载并安装好 Git 3.熟悉 Git 相关命令行操作 二.Git pull & commit(add): 下面简单说一下相关操作: Php ...

  3. python入门之paramiko模块

    paramiko用于实现ssh远程连接服务器执行相关操作. paramiko与之依赖模块cryptography最好版本相同,不然可能执行程序会出错. 一.ssh连接服务器执行命令 import pa ...

  4. 【Java】在eclipse中使用gradle进行项目构建 入门篇

    ##Gradle的安装与配置- Gradle 是以 Groovy 语言为基础,面向Java应用为主,基于DSL(领域特定语言)语法的自动化构建工具. 系统环境变量中添加gradle 前往官网下载Com ...

  5. android 开发-ListView列表显示控件的实现

    列表的显示需要三个元素: 1.ListVeiw 用来展示列表的View. 2.适配器 用来把数据映射到ListView上的中介. 3.数据    具体的将被映射的字符串,图片,或者基本组件. 根据列表 ...

  6. HDU 5501——The Highest Mark——————【贪心+dp】

    The Highest Mark Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  7. orcale错题分析

    删除同义词语法正确的是: Drop  synonym sy nonym_name; 关于Oracle创建间隔分区后,正确的是: 使用partition(分区名)可以查看特定分区内存放的表记录 关于序列 ...

  8. C#数据库(MSSQL)帮助类

    /// <summary> /// 数据库帮助类 /// <author>Devin</author> /// </summary> public se ...

  9. 多个activity之间的数据共享

    Activity之间的数据共享问题起初一看并没有那么纠结,原因在于两点,一来两个Activity之间可以通过回传的方式进行数据的共享,而哪怕是多个Activity之间,也可以通过静态类进行数据的共享. ...

  10. Java并发(六):并发策略

    通过多次优化实例来了解选择并发策略的正确姿势 通过模拟浏览器程序的渲染页面(Page-Rendering)功能,为了方便,假设HTML页面只会包含标签文本和图片以及URL; 第一个版本:串行加载页面元 ...