记一次OC Block循环引用(Retain Cycle)引起的内存泄露

经历这次问题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)引起的内存泄露)