2011-03-13 1 views
2

NSNotification은 주 스레드가 아닌 다른 스레드에서 해당 selector를 호출하기 때문에 UIViews 나 다른 인터페이스 요소에 대한 변경 사항 종종 효력을 발휘하기가 느립니다. 주 스레드가 바쁜 경우 (이것은 종종 광산입니다!) 가장 심각합니다.NSNotifications에 응답 할 때 UIViews를 업데이트하는 가장 좋은 방법은 무엇입니까

"performSelectorOnMainThread :"를 호출하여 문제를 해결할 수 있습니다. 이게 가장 좋은 방법인가요?

- (void) gotMovieSaveFinishNotication: (NSNotification *) not { 
NSURL *exportMovieURL = (NSURL *) [not object]; 
//saving the composed video to the photos album 
ALAssetsLibrary* library = [[[ALAssetsLibrary alloc] init] autorelease]; 

if(![library videoAtPathIsCompatibleWithSavedPhotosAlbum: exportMovieURL]) { 
    NSLog(@"videoAtPathIsCompatibleWithSavedPhotosAlbum fails for: @",exportMovieURL); 
    return; 
} 

[library writeVideoAtPathToSavedPhotosAlbum:exportMovieURL 
          completionBlock:^(NSURL *assetURL, NSError *error) 
{ 
    [self performSelectorOnMainThread:@selector(setTintToNormal) 
          withObject: NULL 
         waitUntilDone: YES]; 

    if(error) 
    { 
     DLog(@"The video saving failed with the following error =============== %@",error);//notify of completion 
    } 
    else 
    { 
     DLog(@"The video is saved to the Photos Album successfully"); 

    } 


}]; 

}

답변

3

NSNotificationCenter는 postNotification과 동일한 스레드에서 알림을 보냅니다! 그래서 그것은 주 스레드 또는 백그라운드 스레드 일 수 있습니다.

Btw, 메인 스레가 아닌 스레드에서 UI를 변경하지 않아야합니다. 즉, 느리게 처리하지 않아도되며, 작업을 수행하지 않아야하며, 넘어 질 수 있습니다.

당신의 솔루션은 확실히 실행 가능하지만, 약간 다른 (그리고 아마도 더 좋은) 방법이 있습니다. 정보를 원하시면이 페이지를 참조하십시오 :

http://www.cocoanetics.com/2010/05/nsnotifications-and-background-threads/

이 요약 문제로 위의 링크 거래의 접근 방식을 실제로 메인 스레드에서 알림을 생성하는 메소드를 호출하여, 카테고리에서 몇 가지 편리한 헬퍼 메소드를 통해 . 유용 할 수 있습니다! 현재 기술을 사용하면 앱에서 알림을받을 때까지 performSelectorOnMainThread 전화가 많이 걸릴 수 있기 때문에 실제 알림 수신 방법에서 performSelectorOnMainThread으로 전화하는 솔루션보다 약간 '깔끔'하다고 느낍니다.

http://cocoadev.com/index.pl?NotificationsAcrossThreads

+0

메인 스레드에서 UIKit 액세스의 위험에 대해 상기 알림 주셔서 감사. 나는 전에 그것을 읽었지만 어떻게 든 진지하게 받아들이지 않았다 :-). 이제 나는 곧고 좁아졌다. –

+0

예, 해당 카테고리 솔루션이 마음에 들었습니다. 특히 이것이 한 곳 이상에서 일어나고 있기 때문에 가장 복잡한 방법처럼 보입니다. 도와 주셔서 감사합니다! –

2

예. 모든 UI 관련 메서드는 주 스레드에서만 호출해야합니다. waitUntilDone을 ​​고려,

dispatch_async(dispatch_get_main_queue(), ^{ 
    // do some stuff on the main thread here... 

    [self setTintToNormal]; 
}); 

을도 :

당신이 다른 옵션은 GCD를 사용하고 주요 큐에 보내는 것입니다 NO. 가능한 한 차단하지 마십시오.

+0

감사합니다, 나는 다른 생각으로이 좋아 -하지만 난 다른 생각 (http://www.cocoanetics.com/로 갈거야 :

또한,이 유용한 정보입니다 2010/05/nsnotifications-and-background-threads /). –