2012-06-27 1 views
1

메인 스레드에서 "작업 진행률"을 나타내는보기를로드하는 동안 백그라운드 스레드에서 실행해야하는 무거운 계산을 수행하는 myButtonAction 메서드가 있습니다. 백그라운드 스레드가 메서드 실행을 완료하자마자 "작업 진행률"뷰를 제거하고 주 스레드에서 다른 뷰를로드해야합니다.스레드 동기화를 보장하는 방법

[self performSelectorInBackground:@selector(myButtonAction) withObject:nil]; 
[self performSelectorOnMainThread:@selector(LoadView) withObject:nil waitUntilDone:YES]; 

내가 직면하고 문제는 myButtonAction가 실행을 완료하기 전에 LoadView의 실행을 완료한다는 것입니다. myButtonAction 실행이 완료된 후에 만 ​​LoadView이 실행을 시작하도록하려면 어떻게해야합니까?

참고 : myButtonAction은 다른 클래스에 메서드 정의가 있습니다.

답변

2

사용 Grand Central Dispatch :

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    [self myButtonAction]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self LoadView]; 
    }); 
}); 

또는, performSelector 방법으로 체류하려는 경우 :

- (void)loadViewAfterMyButtonAction 
{ 
    [self myButtonAction]; 
    [self performSelectorOnMainThread:@selector(LoadView) withObject:nil waitUntilDone:YES]; 
} 
1

당신은 다음을 수행 할 필요가 -

[self performSelectorInBackground:@selector(myButtonAction) withObject:nil]; 

- (void)myButtonAction { 
    //Perform all the background task 

    //Now switch to main thread with all the updated data 
    [self performSelectorOnMainThread:@selector(LoadView) withObject:nil waitUntilDone:YES]; 
} 

편집 - 은 그럼 당신은 시도 할 수 있습니다 -

[self performSelectorInBackground:@selector(buttonActionInBackground) withObject:nil]; 

- (void)buttonActionInBackground { 
     [self myButtonAction]; 

     //Now switch to main thread with all the updated data 
    [self performSelectorOnMainThread:@selector(LoadView) withObject:nil waitUntilDone:YES]; 
    } 

지금 당신이 myButtonAction을 변경할 필요가 없습니다.

[self performSelectorOnMainThread:@selector(LoadView) withObject:nil waitUntilDone:YES]; 

지금은 당연에는 loadView 당신이 함께 할 때까지 그것을 기다릴 말했기 때문에 myButtonAction이 완료되기 전에 완료하는 것이 "waitUntilDone : YES"

+0

'myButtonAction'은 편집하지 않아도되는 다른 클래스에 있습니다. –

+0

@XaviValero - 편집 된 게시물을 확인하고, 원할 경우 GCD로 이동할 수도 있습니다. – rishi

0

는이 코드가 myButtonAction의 끝에서 호출되는 것을 받아 . 마지막에 waitUntilDone : NO로 호출하십시오.

이러한 종류의 문제를 해결하는 간단한 방법은 선택기 호출을 [self performSelector:@selector(sel) withObject:obj afterDelay:0.0] 또는 NSTimer를 사용하여 주 실행 루프에 넣는 것입니다. 예를 들어 UI 업데이트가 완료 될 때까지 기다릴 수 있습니다.

0

나는 이러한 목적을 위해 Semaphore Design Pattern를 사용

[self performSelectorInBackground:@selector(loadViewAfterMyButtonAction) withObject:nil]; 

.

+0

그건 내가 완전히 배 밖으로 부르는거야. 첫 번째 대답에서 제안 된 GCD는 기본적으로 프로그래머에게는 아무런 노력이없고 잘못 이해할 가능성이 거의 없으므로 문제를 매우 쉽게 해결합니다. – gnasher729