2012-05-21 2 views
1

사용자 작업이 온라인 리소스에 연결을 시도하는 앱이 있습니다. 연결 프로세스는 thirdPartySDK에 의해 수행되고 성공 또는 실패는 비동기 적으로 다시 신호로 보냅니다. 이 방법은 알림을 게시하도록 구성된 appDelegate에서 처리합니다. (Dropbox 스타일). 작업이 실행될 때 실패를 가정 아래addObserver를 통해 호출 된 여러 블록 작업 : selector : name : object :

,의 UIAlertView가 여러 번 호출됩니다. 즉, 연결을 반복적으로 테스트하고 실패 할 경우 처음 블록을 한 번 호출하고 두 번째로 블록을 두 번 호출하고 세 번 째 호출을 호출합니다. 블록 작업이 취소되지 않은 경우입니다 또는 대기열에서 제거됩니다. 개체 : 큐 : usingBlock :

if (!opQ) { 
    opQ = [[NSOperationQueue alloc] init]; 
} 

[[NSNotificationCenter defaultCenter] addObserverForName:LINK_NOTIFICATION_FAILURE object:nil queue:opQ usingBlock:^(NSNotification *aNotification) { 

    dispatch_async(dispatch_get_main_queue(), 
    ^{ 
     [[[UIAlertView alloc] initWithTitle:@"Network_Account_Not_Linked" message:@"Your_attempt_to_link_your_account_ended_unsuccessfully" 
      delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; 

     [[NSNotificationCenter defaultCenter] removeObserver:self]; 

    }); 

}]; 

문제는 addObserverForName로 나타납니다. 으로 테스트 addObserver : selector : name : object : 잘 작동합니다 (알림 당 하나의 셀렉터 실행). 블록을 사용하는 것이 더 편리하고 코드를보다 읽기 쉽도록 만들고 지역 변수에 대한 액세스를 제공하므로 내 동기가됩니다.

는 I는 NSBlockOperation 스레드 및 ( 디버거에 따른 "범위 밖"이고 그 시점에서 OPQ)를 dispatch_async에 [OPQ cancelAllOperations] 시도. 또한, 비슷한 결과가 실패한 [NSOperationQueue mainQueue]을 사용했습니다. 또한 알림을 등록하기 전에 새로운 opQ로 시작해 보았습니다 ... nada.

왜 여러 통화가 발생합니까? 블록을 사용하는 더 나은 접근법이 있습니까?

당신이 사용하고있는 방법에 대한

답변

3

애플 문서는 말한다 :

가 관찰 등록을 취소하려면 removeObserver이 메소드에 의해 반환 된 개체를 전달 :. addObserverForName : object : queue : usingBlock :에 의해 지정된 오브젝트가 할당 해제되기 전에 removeObserver : 또는 removeObserver : name : object :를 호출해야합니다.

즉, 옵저버를 제거 할 때 self을 단순히 전달할 수 없습니다.

시도 :

__block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:LINK_NOTIFICATION_FAILURE object:nil queue:opQ usingBlock:^(NSNotification *aNotification) { 

dispatch_async(dispatch_get_main_queue(), 
^{ 
    [[[UIAlertView alloc] initWithTitle:@"Network_Account_Not_Linked" message:@"Your_attempt_to_link_your_account_ended_unsuccessfully" 
     delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; 

    [[NSNotificationCenter defaultCenter] removeObserver:observer]; 

}); 
}]; 
+0

감사합니다. 그것을 시도했지만 작동하지 않았다. id observer = ... 문에서 EXC_BAD_ACCESS를 두 번째받습니다. 나는 opQ를 제거하고 [NSOperationQueue mainQueue]를 사용하여 코드를 단순화했다. 같은 충돌. GCD 제거 ... 같은 사고. – vmanjz

+0

OK, 조금 더 파고 가면이 문제가 8477629와 중복됩니다. 답은'__block id observer = ... '입니다. – vmanjz

+1

의견 바로 앞에'__block id ...' 하 ... 나는 대답을 업데이트 할 것이다 ... –

관련 문제