2013-06-08 1 views
2

왜 이것이 필요한지 확인하고 싶습니다.dispatch_async 내에서 dispatch_sync

이 코드를 KIImagePager (cocoapod)에 추가하여 앱에 로컬 인 이미지를로드합니다 (기본 코드는 URL에서 이미지를로드합니다). 여기

은 내 작업 코드는 동료가 무엇을 제안 오프 기반으로 :

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
       dispatch_sync(dispatch_get_main_queue(), ^{ 
        [imageView setImage:[UIImage imageNamed:[aImageUrls objectAtIndex:i]]];; 
       }); 
      }); 

가 나는 내부 dispatch_sync을 가지고가는 경우에, 그것은하지만 내가 원하는 방식으로 (에서 작동하는 것으로 나타났습니다 이미지에 일부 이미지 스크롤을 시작하면 호출기 스크롤보기가 아직로드되지 않았습니다.) 그러나 그들은 결국로드합니다.

제 질문은 이것입니다. 메인 대기열의 동기화 호출이 이미지를 메인 대기열에있는 UI로 다시 가져 옵니까? 두 번째 비동기가 제거 된 상태에서 작동하기 때문입니다.

+0

코드에서 'async'가 아닌'dispatch_sync'입니다. 무엇 이니? – jrturton

+0

죄송합니다. 맞습니다. –

+0

* 해당 코드의 내부 디스패치는 쉽게 'dispatch_async'가 될 수 있습니다. 이는 'dispatch_sync'보다 저렴합니다. – bbum

답변

2

주 스레드의 UI 개체에서만 작업해야합니다. 그렇지 않으면 몇 가지 문제가 발생할 것입니다. 첫 번째로 보았 듯이 UI 개체는 업데이트가 지연됩니다. 두 번째는 여러 스레드에서 UI 개체를 동시에 변경하려고하면 앱이 다운 될 수 있다는 것입니다. 주 스레드의 UI 개체로만 작업해야합니다.

9

내부 디스패치는 주 스레드에서 코드 블록을 실행합니다. 이것은 모든 UI 작업이 주 스레드에서 수행되어야하기 때문에 필요합니다. 그리고 이미지 다운로드 코드 (이 스 니펫이 실행되는 컨텍스트)는 백그라운드 스레드에있을 수 있습니다.

외부 디스패치는 백그라운드 스레드에서 해당 블록을 실행합니다. 주어진 블록은 주 스레드에서 실행되는 블록입니다. 따라서 외부 블록을 안전하게 제거 할 수 있습니다.

시간 당신이 사용하고있는 관용구의 개요.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
    // do blocking work here outside the main thread. 
    // ... 
    // call back with result to update UI on main thread 
    // 
    // what is dispatch_sync? Sync will cause the calling thread to wait 
    // until the bloc is executed. It is not usually needed unless the background 
    // background thread wants to wait for a side effect from the main thread block 
    dispatch_sync(dispatch_get_main_queue(), ^{ 
     // always update UI on main thread 
    }); 
}); 
+2

동의 할 수 있습니다. 당신의 대답은 아주 분명합니다! – enadun

+0

이므로 dispatch_sync를 dispatch_async로 변경할 수 있습니다. 코드가 더러워 보이지만 여전히 작동합니까 ?? 또한 왜 여기에 dispatch_sync가 사용되는지 자세히 설명 할 수 있습니까? – Nil

관련 문제