循环引用问题 -- dealloc方法不执行

dealloc不执行

若是一个类在释放事后,dealloc方法没有执行,那么就表明着这个类还被其余对象所引用,引用计数不为0,这样就形成了内存泄露json

昨天其余业务线开发告知他所依赖的我这边的父类VC的-dealloc 方法不执行,叫我跟一下函数

因而我很快的想到-dealloc没执行,确定是循环引用内存泄露之类的问题,因而打开instrument,复现着触发步骤,一个红点,两个红点;嘿,就是你了,结果查找call trees事后就蒙蔽了,报错是jsonmodel的实例方法有问题,难道是某个子类化的JsonModel对象引用了这个VC? 可是这个类有接近两千行,我怎么看?指针

因而小组大神出场,其在使用了一番instrument事后,发现确实这个VC在释放事后引用计数不为0,可是从各个内存的使用状况啊,调用堆栈啊并看不出错误是出如今哪里(他说instrument改版后不太会用了),在得知个人业务需求事后,因而叫我去用最笨的办法去解决-- 把全部改动屏蔽掉,而后逐个取消屏蔽,看内存泄露在哪个方法里面code

因而尝试,定位,尝试,定位对象

最终找到循环引用的地方:blog


在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的引用:input

@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的引用。 固然你若是是一个不爱用黄色宏的盆友的话,你能够用原生代码写出来it

__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了

相关文章
相关标签/搜索