2012-04-05 3 views
3

내 전체 스레드를 진행하면서 메인 스레드에서 NSProgressIndicator를 사용하여 진행 상황을 업데이트하고 있습니다. 이제 다른 클래스 파일에서 객체를 호출하고 그 객체가 내 주 스레드의 값으로 돌아갈 때까지 기다릴 때 NSProgressIndicator가 사라질 것입니다. 다른 스레드로부터 반환 값을 얻을 때까지 주 스레드가 차단되어 있기 때문입니다.메인 스레드가 코코아 앱에서 차단되었을 때 UI가 업데이트되지 않습니다.

내 질문은 주 스레드에서 UI를 업데이트하지 않고 차단하고 다른 개체를 백그라운드에서 실행하고 필요에 따라 주 스레드에 값을 반환하는 데 권장되는 방법입니다. 블록을 사용하는 방법을 알고 있지만 블록 연산은 값을 반환 할 수 없습니다. 는 내가 필요하면이 의사 코드를하는 데 도움이 무언가이다 :

-(IBAction) main { 

//Update progress indicator UI to show progress 
//perform an call to another object from another class. 
// wait till i get its return value. 
//Update progress indicator UI to show progress 
// Use this return value to do something. 
//Update progress indicator UI to show progress 


} 

다른 객체에 대한 호출이 이루어지면, 내가 메인 스레드가 차단되어 있기 때문에 나는 완전히 가지고있는 확정 NSProgressIndicator가 사라집니다. 감사.

답변

9

귀하의 위의 코드가 올바른 방법이 아닙니다. main이 결코 반환하지 않기 때문에 진행 표시기는 절대로 업데이트되지 않습니다. 주 스레드에서 빨리 돌아와야합니다.

대신, 다양한 지점에서 주 스레드의 진행률 표시기를 업데이트하는 백그라운드 블록을 설정해야합니다. 그래서, 예를 들어 :

- (IBAction)start:(id)sender { 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 

    dispatch_async(queue, ^{ 
    dispatch_async(dispatch_get_main_queue(), ^{[self.progress setProgress:0];}); 

    // Doing some stuff 
    dispatch_async(dispatch_get_main_queue(), ^{[self.progress setProgress:.25];}); 

    // Doing more stuff 
    dispatch_async(dispatch_get_main_queue(), ^{[self.progress setProgress:.75];}); 
    }); 
} 

은 (예,이 self을 유지하는 대기열이 발생하지만, self 큐를 유지하지 않기 때문에이 여기 괜찮습니다.) 당신의 작업이 실행되어야처럼

4

GCD (Grand Central Dispatch)로 원하는 것을 얻을 수 있습니다. 여기

당신이 시작하는 예입니다

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); 
    dispatch_async(queue, ^{ 
     // Perform async operation 
       dispatch_sync(dispatch_get_main_queue(), ^{ 
        // Update UI 
       }); 
    }); 
+2

여기서 'dispatch_release'를 호출하지 마십시오. 이 대기열을 만들지 않아서 해제하지 않아야합니다. –

+0

@RobNapier 당신은 절대적으로 옳다. 고지에 대한 내 대답, 고맙습니다 – Alladinian

+0

편집이 코드를 추가 할 때 내 다른 메서드 정의를 찾을 수 없다는 오류가 발생합니다. 어떤 아이디어? – cocoacoder

0

그것은 소리 별도의 스레드가 여러 가지 방법으로 수행 할 수 있지만 NSOperationQueue 및 사용자 지정 NSOperation 클래스 (이 값을 설정하는 것보다 쉽습니다) 또는 NSInvokeOperation 클래스 사용을 사용하면 가장 쉽게 얻을 수 있습니다.

그런 다음 NSNotificationCenter를 사용하여 메인 스레드에서 메시지를 클래스로 다시 보내거나 KVO (Key-Value Observing)를 사용하여 옵저버로 설정할 수 있습니다.

결론적으로 다양한 선택을 할 수 있으며 최선의 기술력을 갖추려면 기본 기술을 이해해야합니다. 저는 Apple의 Threaded Programming Guide으로 개인적으로 시작한 다음 두 번째로 읽어서 솔루션을 만들기 전에 모든 장점을 추출했는지 확인하십시오.

관련 문제