0

이 질문은 이전에 물어 보았지만 해결 방법 중 어느 것도 내 문제를 해결하지 못하므로 다시 질문 할 것입니다. 내가 블록을 통해 콜백의 결과로 자기에 대한 메서드를 호출하려고합니다. 나는 다음과 같은 오류 받고 있어요 :Objective-C는 ARC가있는 블록을 올바르게 사용합니까?

이 블록에 강력하게 '자기'를 캡처하는 것은 사이클을

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    self.webClient.completionHandler = ^{ 
     [self populateData]; 
    }; 
} 
나는 아래의 코드와 같은 일을 시도

을 유지 이어질 가능성, 그리고 나는 아직도 해요 같은 경고를 받는다. 해결책은 무엇입니까?

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    __weak id weakSelf = self; 
    self.webClient.completionHandler = ^{ 
     [weakSelf populateData]; 
    }; 
} 
+1

__weak 행을 블록 안에 넣고 있습니까? 그렇다면 완료 핸들러를 설정하거나 블록을 정의하는 행 앞에 있어야합니다. – UIAdam

+0

예 앞에서 [self populateData] – aryaxt

+0

블로어 내부의 모든 작업을 수행 할 수 있도록 더 청결한 weay가 있습니까? – aryaxt

답변

4

코드는 다음과 같아야합니다.

먼저 경고를 받았습니까?

자체는 webClient에 대한 강력한 참고 자료입니다. webClient에는 completionHandler에 대한 강력한 참조가 있습니다. completionHandler에는 self에 대한 강력한 참조가 있습니다. 따라서 프로그램의 다른 모든 참조가 사라지면이주기의 각 항목에 대한 강력한 참조가 있으므로 할당을 취소 할 수 없습니다.

물론 작동하지 않습니다

__weak id myself = self; 
[myself populateData]; 

를 작성하는 시도. 블록은 자신에게 할당하기 때문에 여전히 자기를 참조합니다. 그래서 여기에는 차이점이 없습니다.

__weak 아이디 weakSelf = 자기를 작성 UIAdam의 솔루션; self.webClient.completionHandler =^{ [weakSelf populateData]; };

은 weakSelf가 약한 참조이며 블록이 자체에 대한 약한 참조 만 포함한다는 것을 의미합니다. 따라서 자기에 대한 다른 모든 강력한 언급이 없어지면 약한 참조 만 남았습니다. 약한 참조는 자기 자신을 유지하지 않으므로 자기는 할당 해제됩니다.

이제 어떻게 될지 모르지만 webClient에 대한 강력한 참조가 있었고 블록이 호출되었습니다. weakSelf는 약한 참조이며 약한 참조는 객체가 할당 해제 될 때 nil로 설정됩니다. 그래서 당신은 블록이 콜 될 때 약한 자신이 없다는 것을 준비해야합니다. 블록 내부에

id strongSelf = weakSelf; 
[strongSelf populatedData]; 

을 쓰는 것이 좋습니다. strongSelf를 nil로 설정하거나 self로 설정할 수 있습니다. 그러나 그것은 강력한 참고이기 때문에 블록이 끝날 때까지 0이 아닌 상태를 유지합니다. 처음부터 시작하는 게 아니라면.

0

UIAdam 올바른 대답을했다하지만 정확한 이유는 이해 가치 :

__weak id myself = self; 
[myself populateData]; 
+0

"실제로 작성하는 것이 좋습니다."이 경우에는 차이점이 없습니다. – newacct

관련 문제