美文网首页
记一次OC Block循环引用(Retain Cycle)引起的

记一次OC Block循环引用(Retain Cycle)引起的

作者: devzhaoyou | 来源:发表于2018-11-10 13:16 被阅读16次

    经历这次问题iOS平台Block循环引用(Retain Cycle)感觉是个很容易出现的问题,项目中有一个相机采集的类 CameraCapturer, 造成内存泄露代码:

    [_rawDataOutput setI420FrameAvailableBlock:^(const GLubyte *outputBytes, uint8_t *bytes_y, int stride_y, uint8_t *bytes_u, int stride_u, uint8_t *bytes_v, int stride_v, NSInteger width, int height) {
        ......
        ......
        ......
        if(_owner)  {
            _owner->IncomingI420VideoFrame(&videoFrame, 0);
        }
    }];
    

    _owner 为类成员变量, 在 OC的 block 块中被引用,此时 CameraCapturer 对象的引用计数器会被 +1,当该类要被释放时,首先要释放上面的 block,而 block的释放又要依赖 CameraCapturer对象的释放,造成:循环引用(Retain Cycle),最终 CameraCapturer 对象的 引用计数器不能置位0,- dealloc 不能被调到,造成内存泄露。
    解决方法:

    self 转换为 weak 弱引用,在 block 中将 self 若引用转化为 strong 强应用,然后在使用 _owner 成员变量即可,代码如下:

    __weak typeof(self)weakSelf = self;
    [_rawDataOutput setI420FrameAvailableBlock:^(const GLubyte *outputBytes, uint8_t *bytes_y, int stride_y, uint8_t *bytes_u, int stride_u, uint8_t *bytes_v, int stride_v, NSInteger width, int height) {
        ......
        ......
        ......
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if(strongSelf->_owner)  {
            strongSelf->_owner->IncomingI420VideoFrame(&videoFrame, 0);
        }
    }];
    

    相关文章

      网友评论

          本文标题:记一次OC Block循环引用(Retain Cycle)引起的

          本文链接:https://www.haomeiwen.com/subject/irezxqtx.html