zoukankan      html  css  js  c++  java
  • 循环引用问题 -- 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了

  • 相关阅读:
    .NET常见问题收集
    .NET 常用转换
    Android 百度地图开发setOnTouchListener方法给mapView设置了OnTouchListener后地图无法拖动的问题
    Android_参考
    常用操作
    Android开发笔记——Eclipse 关联Android源码
    Android开发笔记静态变量问题
    无法载入 mysql 扩展,<br />请检查 PHP 配置 解决办法
    服务器维护
    cocos2d 左下角三行
  • 原文地址:https://www.cnblogs.com/WayneLiu/p/5896611.html
Copyright © 2011-2022 走看看