programing tip

iPhone-그랜드 센트럴 디스패치 메인 스레드

itbloger 2020. 6. 15. 21:51
반응형

iPhone-그랜드 센트럴 디스패치 메인 스레드


내 앱에서 성공적으로 중앙 집중식 디스패치를 ​​사용했지만 다음과 같은 것을 사용하면 실제로 어떤 이점이 있는지 궁금합니다.

dispatch_async(dispatch_get_main_queue(), ^{ ... do stuff

또는

dispatch_sync(dispatch_get_main_queue(), ^{ ... do stuff

두 가지 경우 모두 메인 스레드에서 실행될 블록을 실행하는 것입니다. 앱이 실행되는 정확한 위치이며로드를 줄이는 데 도움이되지 않습니다. 첫 번째 경우 블록이 실행될 때 제어 할 수 없습니다. 블록을 발사 한 후 0.5 초 동안 블록이 실행되는 경우를 보았습니다. 두 번째 경우는

[self doStuff];

권리?

나는 당신들이 어떻게 생각하는지 궁금합니다.


메인 큐로 블록 디스패치는 일반적으로 백그라운드 큐에서 수행되어 일부 백그라운드 처리가 완료되었음을 알립니다.

- (void)doCalculation
{
    //you can use any string instead "com.mycompany.myqueue"
    dispatch_queue_t backgroundQueue = dispatch_queue_create("com.mycompany.myqueue", 0);

    dispatch_async(backgroundQueue, ^{
        int result = <some really long calculation that takes seconds to complete>;

        dispatch_async(dispatch_get_main_queue(), ^{
            [self updateMyUIWithResult:result];
        });    
    });
}

이 경우 백그라운드 큐에서 긴 계산을 수행하고 계산이 완료되면 UI를 업데이트해야합니다. UI 업데이트는 일반적으로 기본 대기열에서 수행해야하므로 두 번째 중첩 dispatch_async를 사용하여 기본 대기열로 '신호'합니다.

메인 큐로 다시 디스패치 할 수있는 다른 예가있을 수 있지만 일반적으로이 방법으로 수행됩니다. 즉, 백그라운드 큐로 디스패치 된 블록에서 중첩됩니다.

  • 백그라운드 처리 완료-> UI 업데이트
  • 백그라운드 큐에서 처리 된 데이터 청크-> 다음 청크를 시작하도록 기본 큐 신호
  • 백그라운드 큐의 수신 네트워크 데이터-> 메시지가 도착했다는 메인 큐에 신호를 보냅니다.

왜 당신은 메인 큐 에서 메인 큐로 디스패치하고 싶을 까요? 글쎄, 일반적으로 다음 번에 루프를 실행하기 위해 몇 가지 작업을 예약하도록 할 수는 없습니다.


메인 스레드에서 메인 큐로 블록을 전달하는 것이 유용 할 수 있습니다. 메인 큐가 큐에 대기 된 다른 블록을 처리 할 수있는 기회를 제공하므로 다른 모든 항목의 실행을 차단하지 않습니다.

예를 들어 많은 동시 연결을 처리하는 본질적으로 단일 스레드 서버를 작성할 수 있습니다. 대기열의 개별 블록이 너무 오래 걸리지 않는 한 서버는 새로운 요청에 응답합니다.

만약 당신의 프로그램이 이벤트에 응답하는 데 평생을 보낸다면 이것은 자연 스러울 수 있습니다. 메인 큐에서 실행되도록 이벤트 핸들러를 설정 한 다음 dispatch_main ()을 호출하면 스레드 안전성에 대해 전혀 걱정할 필요가 없습니다.


dispatch_async와 dispatch_sync의 차이점에 대해 궁금한 점에서 귀하의 질문을 올바르게 이해하고 있습니까?

dispatch_async

블록을 비동기 적으로 대기열에 발송합니다. 의미하는 것은 블록을 큐에 보내고 메소드에서 나머지 코드의 실행을 계속하기 전에 블록이 돌아 오기를 기다리지 않는다는 의미입니다.

dispatch_sync

블록을 동 기적으로 대기열에 발송합니다. 이렇게하면 블록의 실행이 끝날 때까지 메소드에 남아있는 코드가 더 이상 실행되지 않습니다.

나는 주로 dispatch_async메인 큐에서 작업을 수행하고 장치가 가질 수있는 추가 코어를 활용하기 위해 백그라운드 큐를 사용했습니다 . 그런 다음 dispatch_asyncUI를 업데이트 해야하는 경우 기본 스레드로 이동하십시오.

행운을 빕니다


유용한 작업 중 하나는 긴 작업 전에 스피너 설정과 같은 UI 활동에 유용합니다.

- (void) handleDoSomethingButton{

    [mySpinner startAnimating];

    (do something lengthy)
    [mySpinner stopAnimating];
}

긴 일 동안 메인 스레드를 차단하고 실제로 UIKit이 스피너를 시작하지 못하게하기 때문에 작동하지 않습니다.

- (void) handleDoSomethingButton{
     [mySpinner startAnimating];

     dispatch_async (dispatch_get_main_queue(), ^{
          (do something lengthy)
          [mySpinner stopAnimating];
    });
}

실행 루프로 제어를 반환하여 UI 업데이트를 예약하고 스피너를 시작한 다음 디스패치 큐에서 다음 항목을 가져옵니다. 실제 처리입니다. 처리가 완료되면 애니메이션 중지가 호출되고 실행 루프로 돌아가 UI가 중지로 업데이트됩니다.


스위프트 3, 4 및 5

메인 스레드에서 코드 실행

DispatchQueue.main.async {
    // Your code here
}

Async means asynchronous and you should use that most of the time. You should never call sync on main thread cause it will lock up your UI until the task is completed. You Here is a better way to do this in Swift:

runThisInMainThread { () -> Void in
    // Run your code like this:
    self.doStuff()
}

func runThisInMainThread(block: dispatch_block_t) {
    dispatch_async(dispatch_get_main_queue(), block)
}

Its included as a standard function in my repo, check it out: https://github.com/goktugyil/EZSwiftExtensions

참고URL : https://stackoverflow.com/questions/7905192/iphone-grand-central-dispatch-main-thread

반응형