2012-12-03 5 views
1

나는 직면하고있는 상황에 대해 작은 의문을 가지고 있습니다. asyncTaskFinished라는 콜백이 단지 배경 작업입니다콜백 = 동시성으로 선택기를 수행 하시겠습니까?

- (void)firstSelector { 
    [self launchAsyncTask]; 
    ... do some work for a long time (10secs) ... 
} 

- (void)asyncTaskFinished { 
    ... some work after 5secs of async task ... 
} 

firstSelector 수행 launchAsyncTask : 나는 2 가지 방법이있다. 비동기 작업을 시작한 후 특정 시간 동안 firstSelector이 실행되고 (10 초라고 가정) 비동기 작업이 5 초 동안 실행된다고 가정하면 동시성 문제가 발생합니까?

어떻게 작동합니까? asyncTaskFinishedfirstSelector 뒤에 실행되거나 firstSelector이 일시 중지되어 asyncTaskFinished을 실행합니까?

실행 루프가있는 링크가 있습니까? 메소드를 큐에 추가 한 다음 호출 할 때 실행됩니까?

은 내가 잃었어요 :)

감사합니다.

+0

문서를 읽었습니까? http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html? 나는 당신이 어떤 특별한 질문을 할 때까지 모든 것을 설명한다고 믿습니다. –

+0

내 콜백이 주 스레드 실행 루프를 사용하여 대기 중임을 이해하지만 firstSelector는 어떻습니까? 나는 표준 "[self firstSelector];"를 사용하여 그것을 수행한다. 그것은 또한이 방법으로 대기 중입니까? –

+0

'콜백'은 일반적으로 주 '작업'과 동일한 스레드에서 시작됩니다. 주 스레드뿐만 아니라 모든 스레드가 될 수 있습니다.토론 할 코드가 없으므로 detached 스레드에서'firstSelector'가 호출되고'launchAsyncTask'가 또 다른 백그라운드 스레드를 생성하는 것이 일반적으로 가능합니다. 또는 둘 모두에 대해 동일한 주/분리 스레드 일 수 있으며, 그 중 하나는 분리 된 스레드의 주 스레드와 다른 스레드에 있습니다. 메인 스레드에서 항상 콜백을 시작하기로 결정할 수도 있습니다. 그것은 모두 디자인에 의해 주도되며 항상 각 시나리오가 다르기 때문에 잘 문서화되어야합니다. –

답변

1

비동기 작업은 UI가 주 루프에서 실행되는 동안 주 실행 루프에서 실행되지 않는 비동기 적으로 실행됩니다. Concurrency Programming Guide을 살펴보십시오.

그래서 여기서는 동기화 시간이 얼마나 오래 걸릴지 잘 모릅니다. 10 초가 걸리 겠지만 완전히 확신 할 수는 없습니다. 따라서이 경우 비동기 작업이 주 스레드에서 완료되면 블록으로 작업하거나 asyncTaskFinished 함수를 트리거하는 방법을 찾아야합니다. 간단한 블록 콜백을 정의한 다음 비동기 태스크가 완료되면 함수를 트리거 할 수 있습니다.

비동기 작업에 GCD를 사용하면 정말 쉽습니다. 당신은이 정도만 할 것입니다. onThread : 당신은 동시성 NSThread를 사용하는 경우

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     [self runMyAsyncTask]; 
     // trigger the main completion handler when this completed 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self asyncTaskFinished]; 
     }); 
    }); 

당신은 performSelector를 사용할 수있는 비동기 작업이 완료되면 완료 선택을 트리거 할 수 있습니다. 간단한 경우를 위해 콜백 핸들러를 구현하는 방법을 보여 드리겠습니다. 비동기 작업을 트리거하기 위해 다음과 같은 함수를 만들 수 있습니다.

-(void)launchAsyncTaskWithCompletionHandler:(void(^)(void))completionHandler{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     [self runMyAsyncTask]; 
     // trigger the main completion handler when this completed 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      completionHandler(); 
     }); 
    }); 
} 

그리고 비교적 간단합니다.

[self launchAsyncTaskWithCompletionHandler:^{ 
     [self asyncTaskFinished]; 
    }]; 

이것은 이해하기 쉽고 코드를 훨씬 명확하게 만듭니다. 희망이 당신을 도와줍니다.

+0

고맙습니다. 나는 당신이 쓴 것을 이해하고 이미 이러한 개념을 알고 있습니다. 메서드 A가 실행되고 다른 엔티티의 콜백 B가 동일한 스레드에서 호출 될 때 발생하는 질문이 있습니다 (그러나 메서드 A는 아직 완료되지 않았습니다). 두 메서드가 모두 실행 루프를 사용하여 대기중인 경우에는 문제가 없습니다. 콜백에서는 -performSelector ...가 실행 루프를 사용한다는 것을 알고 있기 때문에 문제가 아닙니다. –

+0

하지만 A가 대기열에 들어 있지 않은 경우 (여기에 [self methodA]를 사용할 때 코코아로 어떤 일이 발생하는지 전혀 알지 못합니다.), 질문이 발생합니다 (A가 실행되고 B가 수행됩니다 질문은 A가 대기열에 없기 때문에 언제, 어떻게됩니까?). –

+0

@Nicolas 문서의 '대기열 작업 수행'섹션을 참조하십시오. https://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html 사용 가능한 직렬/동시 대기열에 대한 설명. –

0

스레드의 실행 루프는 입력 소스의 작업을 순차적 (비 동시성) 방식으로 실행합니다. 따라서 firstSelectorasyncTaskFinished이 같은 실행 루프에서 실행되는 한 걱정할 필요가 없습니다. 이것은 콜백 의미에 따라 달라집니다. 비동기 콜백 기능이 올바른 스레드에서 실행되도록하려면 performSelector:onThread:withObject:waitUntilDone:과 같은 것을 사용해야 할 수도 있습니다.

관련 문제