OC 블록 반복 참조(Retain Cycle)로 인한 메모리 유출을 기록합니다.

1483 단어
이번 문제를 겪은 iOS 플랫폼 블록 순환 인용(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.메모리 유출을 초래하다.해결 방법:selfweak 약인용으로 바꾸고 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);
    }
}];

좋은 웹페이지 즐겨찾기