2011-12-02 2 views
9

좋아, 그래서 나는 self 내가 이런 식으로 호출 스택에 깊은 중첩 된 블록 내에서 방법에서 자기에게 메시지를 보낼 방법의 경우에 대한 블록 사이클을 유지하지 않도록하는 방법을 이해 :블록 및 호출 된 메서드에서 자기

- (void)methodA { 
    __block MyClass *blockSelf = self; 
    [someObject block:^{ 
     [blockSelf methodB]; 
    }]; 
} 

- (void)methodB { 
    ... 
    [self methodC]; 
    ... 
} 

- (void)methodC { 
} 

이 경우 [blockSelf methodB]은 괜찮 으면서, methodB에서 [self methodC]을 보내주기를 유지하고 있습니까? 어디에서나 대답을 찾을 수 없습니다 ...

답변

8

거기에 유지주기가 없습니다. 메서드 내에서 블록 리터럴이 정의되면 블록에서 캡처 할 수있는 컨텍스트는 해당 메서드 내부에 보이는 으로 제한됩니다. 당신의 예에서 :

,
- (void)methodA { 
    __block MyClass *blockSelf = self; 
    [someObject block:^{ 
     [blockSelf methodB]; 
    }]; 
} 

블록은 문자 그대로, 즉 : 모든 목적에 사용 가능한 매개 변수 숨겨진

  1. self_cmd :

    ^{ 
        [blockSelf methodB]; 
    } 
    

    은 다음을 참조 할 수있다 -C 방법. -methodA에 형식 매개 변수가있는 경우 블록 리터럴도이를 볼 수 있습니다.

  2. 함수/메소드 블록 내부의 모든 블록 범위 변수, 즉 메소드 내부의 모든 로컬 변수이며 블록 리터럴이 정의 된 지점에서 볼 수 있습니다. 위의 예에서 -methodA의 유일한 로컬 변수는 blockSelf입니다.이 변수는 __block - 지정되었으므로 유지되지 않습니다.
  3. 모든 파일 범위 변수 (일명 글로벌 변수).

블록 리터럴은 다른 함수/메서드 내부에서 일어나는 일을 인식하지 못하기 때문에 (일반적으로 인식 할 수 없음) 호출 된 함수/메서드 내에서 사용할 수있는 컨텍스트는 블록 리터럴에 의해 캡처되지 않습니다. Block 리터럴이 정의 된 메서드에 대해서만 신경 써야합니다.

C 블록을 언급 할 때 폐쇄/람다 (즉, ^{})와 소문자 블록에 참조 할 때 내가 활용 블록의 애플의 규칙을 사용하고 있습니다 (즉, {}).

+0

쿨, 고마워! 이것은 내 도우미 메서드에서 못생긴 "매개 변수 해킹"을 제거합니다 ... – Tom

+0

"거기에 유지주기가 없습니다." 그것은'someObject'가 무엇인지, 그리고 그것이 전달 된 블록을 유지하는지 여부에 달려 있습니다. 'self'가'someObject' (예를 들어, 인스턴스 변수)를 유지하고'someObject'가'block :'에 전달 된 블록을 저장하고 보유하면, 유지 사이클이 생깁니다. – newacct

관련 문제