1

블록에 약한 참조 속성을 가진 클래스가 있습니다. 이 같은이 블록을 사용하는 클래스의 다른 지점에서약하게 유지 된 블록이 "자체"를 캡처 할 때 보유주기를 발생시키는 방법

@interface BlockTest : NSObject 
    @property (nonatomic, weak) void(^testBlock)(); 
@end 

:

- (void)foobar { 
    self.testBlock = ^{ 
     [self doSomething]; 
    }; 
} 

컴파일러 (애플 LLVM 3.0) self 강하게 여기에 포착되기 때문에 유지주기가있을 수 있습니다 뿌려줍니다. 그러나 블록 자체가 __weak 참조이므로 유지주기가 어떻게되는지 알 수 없으므로 문제가되지 않습니다. ARC 약한 참조를 올바르게 이해했다면 -foobar 메서드가 self.testBlock으로 전달 된 블록을 반환 할 때 할당 해제되어야하며 그렇지 않은 경우 self을 릴리스해야합니다.

컴파일러가 계속 유지주기가 있다고 생각하는 이유는 무엇입니까?

+0

설치 프로그램이 거의 쓸모가 없습니다. 블록은 함수에 대한 강력한 참조가 없으므로 함수가 종료 된 후 즉시 할당이 해제됩니다. 속성은'nil'이 될 것입니다. – newacct

+0

그건 보편적으로 사실이 아닙니다. 전역 및 스택 블록은 유지되거나 해제되지 않으므로 할당 후에도 유효합니다 (현재 범위 끝까지의 스택 블록). 또한 그것은 단지 샘플입니다. 아이디어는 블록을 주변에 유지하는 것이 아닙니다. IIRC이 질문을 할 때 나는 경고를 발생시키지 않으면 서'self'라는 메서드의 콜백 블록에'self'를 포착 할 방법을 찾고있었습니다. – Alfonso

답변

8

블록은 블록 자체를 참조하는 방법에 관계없이 블록 내의 개체를 강력하게 캡처합니다. 유지주기 경고는 바로 그 가능성에 대한 경고입니다. 이 사용으로 유지주기가 발생하지 않는다는 것을 앱의 컨텍스트를 기반으로 알면 안전하게 무시할 수 있습니다.

__weak typeof(self) weakSelf = self; 
self.testBlock = ^{ 
    [weakSelf doSomething]; 
}; 

내가 강한 참조로하여 블록의 속성을 변경 것하고 위를 수행하십시오 경고를 없애려면, 다음과 같이 강하거나 약한 중개자를 통해 자기를 전달할 수 있습니다.

+0

좋아, 나는 이것을 피할 수 있었으면 좋겠다고 생각했지만, 보이는 것처럼 이것이 갈 길이다. 감사! – Alfonso