12

다음 코드에서는 옵저버가 절대로 제거되지 않는 이유에 대해 혼란스러워합니다. 내 viewDidAppear에서 나는 다음과 같습니다왜 NSNotificationCenter에서 옵저버를 제거하지 못합니까? addObserverForName : usingBlock get

-(void)viewDidAppear:(BOOL)animated{ 

id gpsObserver = [[NSNotificationCenter defaultCenter] 
          addObserverForName:FI_NOTES[kNotificationsGPSUpdated] 
          object:nil 
          queue:[NSOperationQueue mainQueue] 
          usingBlock:^(NSNotification *note){ 

           NSLog(@"run once, and only once!"); 

       [[NSNotificationCenter defaultCenter] removeObserver:gpsObserver]; 

     }]; 

} 

관찰자가 제거 결코 극복하고 문이 통지가 발송 될 때마다 출력됩니다. 누구든지 어떤 지침을 제공 할 수 있습니까?

답변

28

블록을 addObserverForName:까지 스택에 푸시하면 메소드가 아직 반환되지 않으므로 gpsObserver는 nil (ARC 아래) 또는 garbage/undefined (ARC가 아님)입니다. 외부 변수 __block을 사용하여 변수를 선언하면됩니다.

__block __weak id gpsObserver; 

gpsObserver = [[NSNotificationCenter defaultCenter] 
          addObserverForName:FI_NOTES[kNotificationsGPSUpdated] 
          object:nil 
          queue:[NSOperationQueue mainQueue] 
          usingBlock:^(NSNotification *note){ 

           NSLog(@"run once, and only once!"); 

       [[NSNotificationCenter defaultCenter] removeObserver:gpsObserver]; 

     }]; 

나는 (매트의 대답에 따라) 더 메모리 누수가 없는지 확인하는 __weak을 추가했습니다. 코드가 테스트되지 않았습니다.

+0

이는 의미가 있으며 예상대로 작동합니다. 도와 줘서 고마워. – warpedspeed

11

실제로 관찰자가 __block__weak으로 표시되어 있지 않으면 메모리 누수가 있습니다. Instruments를 사용하여 self이 지나치게 많이 사용되지 않도록하십시오. 나는 그것이 틀림 없음을 확신한다. 그러나 이것은 (실제 코드에서) 올바르게 작동합니다.

__block __weak id observer = [[NSNotificationCenter defaultCenter] 
    addObserverForName:@"MyMandelbrotOperationFinished" 
    object:op queue:[NSOperationQueue mainQueue] 
    usingBlock:^(NSNotification *note) { 
     // ... do stuff ... 
     [[NSNotificationCenter defaultCenter] 
      removeObserver:observer 
      name:@"MyMandelbrotOperationFinished" 
      object:op]; 
}]; 
+0

실제로 관찰자를 유지할 필요가없는 동일한 방법을 소개하고 단순히 선택자 대신 블록을 사용하여 스스로를 사용하는 것이 좋으면 좋겠다. – Eugene

+2

'NSNotificationCenter'에서 제거한 후'nil'으로 설정하면'observer'를'__weak' 할 필요가 없습니다. 저는 이것을 Instruments와 점검했습니다. –

+0

이것은 훌륭한 코드 조각입니다. – Andy