0

我有一些重量級的內容要從數據庫中加載並顯示在屏幕上。 但是同時還有一個'plist到數據庫'保存正在進行的背景任務。 因此UI卡住了。dispatch_async不能與後臺線程

我使用的波紋管的代碼,

對於數據的基礎上獲取和UI更新方法

- (void)performBlockInBackground:(dispatch_block_t)taskBlock 
           completion:(dispatch_block_t)completionBlock 
          withPriotity:(dispatch_queue_priority_t)piority 
{ 
    __block dispatch_block_t taskBlockRef = taskBlock; 
    __block dispatch_block_t completionBlockRef = completionBlock; 

    dispatch_async(dispatch_get_global_queue(piority, 0), ^{ 

     dispatch_sync(dispatch_get_global_queue(piority, 0), taskBlockRef); 

     dispatch_async(dispatch_get_main_queue(), completionBlockRef); 
    }); 
} 

我打電話來了 '的plist,以DB' 的方法

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

這裏的taskBlock是重數據庫提取,而completionBlock是UI更新。

如果我在一段時間後(在syncData方法完成之後)調用此方法,那麼它會順利更新。但是,如果它尚未完成,那麼界面卡住了。

這似乎是線程死鎖的問題,但在這個

請幫忙看不清楚!

+0

爲什麼要在全局隊列上調用dispatch_sync()?你想通過使其同步實現什麼? – jkh

+0

我想'taskBlock'被稱爲簡單的方法。這樣就可以準備數據並按時完成該塊,然後轉到完成塊,該塊將在主線程上運行以進行UI更新。基本上,它的一般方法(如調用但帶有塊)使其像Process一個塊,當'完成'在另一個塊中更新UI時。 – infiniteLoop

回答

3

當您已經進入正確的隊列時,您不需要dispatch_sync()。你可以這樣調用塊:taskBlock()

- (void)performBlockInBackground:(dispatch_block_t)taskBlock 
        withPriority:(dispatch_queue_priority_t)priority 
      completionOnMainThread:(dispatch_block_t)completionBlock 
{ 
    dispatch_async(dispatch_get_global_queue(priority, 0), ^{ 
    if (taskBlock) { 
     taskBlock(); 
    } 

    if (completionBlock) { 
     dispatch_async(dispatch_get_main_queue(), completionBlock); 
    } 
    }); 
} 

會發生什麼情況是這樣的:

  • 立即將工作提高到一個後臺線程。現在我們不阻止調用線程或主線程。
  • 如果我們有一個taskBlock,現在就做。 TaskBlock是您放置數據的地方。
  • TaskBlock完成。
  • 如果我們有一個completionBlock,發送到主線程。 CompletionBlock是您更新用戶界面的地方。