0

나는 블록 변수를 가지고 블록 변수를 가지고 블록이 "self"를 유지하면 retain cycle을 일으키고, 블록을 사용하면 메모리 누수가 발생할 것이라는 벤다도의 글을 읽었습니다. GCD 같은 문제가 발생합니다 사용하는 이유왜 GCD 블록에 "self"를두면 메모리 누수가 발생합니까?

How do I avoid capturing self in blocks when implementing an API?

는하지만 이해가 안 돼요? dispatch_async()와 같은 함수는 클래스 자체에서 캡처해서는 안되는 로컬 변수처럼 보입니다.

그리고 공식 문서는 우리의 객체가 제 시간에 공개되도록하기 위해 블록에 autorelease를 넣어야한다고 말했습니다.

내 IOS 프로젝트의 대부분에서

,이 같은 GCD를 사용

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,(unsigned long)NULL), ^(void) { 

    NSDictionary *resultDic = [MyService loadData]; 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self.delegate useData:resultDic]; 
    }); 
}); 

가 지금은

__block MyClass *blockSelf = self; 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,(unsigned long)NULL), ^(void) { 

    @autoreleasepool{ 
     NSDictionary *resultDic = [MyService loadData]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      @autoreleasepool{ 
       [blockSelf.delegate useData:resultDic]; 
      } 
     }); 

    } 
}); 

에 그들 모두를 변경해야?

더러워 보입니다. 누구나 올바른 방법으로 실마리를 알 수 있습니까?

나는 블록에서 일부 함수를 호출하고 해당 함수에서 "self"또는 "self.delegate"를 사용하면 모든 것을 다른 것으로 변경해야한다는 의미입니까? (그리고 그것을 해결하기 위해 무엇을 해야할지 모르겠다)

FYI, 내 IOS 프로젝트는 IOS8.1 및 비 -ARC 환경에서 빌드됩니다.

+2

주제 약간 벗어남 : 자신에게 유리하게 ARC로 전환해야합니다. –

+0

내가 링크 된 소식을 잘 이해하지 못했습니다. 그것은'@ autoreleasepool'을 언급하지 않습니다. 왜냐하면 그것은 retain 사이클을 깨지 않기 때문입니다. – Tommy

+0

그것은 레거시 코드이며 아무 것도 할 수 없지만 ARC가 아닌 나머지로 남겨 둡니다. 예, @autoreleasepool 문제는 여기에 적어 놓은 링크 대신 Apple 개발자 문서의 공식 기사에 언급되어 있습니다. –

답변

2

@autoreleasepool은 필요하지 않습니다.

블록을 dispatch_async으로 전달하면 블록이 힙으로 복사되지만 (블록 _ 복사) 블록이 호출 된 직후에 해제됩니다 (Block_release). 그래서 아무 사이클 거기에 유지합니다.

모든 블록에 당신은 self이 블록 또는 블록에 대한 강한 참조 체인에 대한 강한 참조가있는 경우, 당신은 사이클을 유지 피하기 위해 __block MyClass *blockSelf = self;를 사용해야 프로젝트에 사용하고 있습니다.

참고 : __block MyClass *blockSelf = self;은 ARC가 아닌 곳에서 작동합니다. ARC로 이전하는 경우 대신 __weak을 사용하십시오.