2

我有一個耗時的過程,並有一個進度指示器顯示用戶已經走了多遠。因爲我必須在主線程上執行消耗的事情,所以我沒有選擇只是在更新之間調度主隊列上的更新。我必須切換到後臺線程一段時間,以便在切換回來並繼續之前讓UI更新。用戶界面回調塊for循環

這是我的,但它感覺非常非正統。有沒有更好的方式來做「阻止循環與UI的回調」在那裏,我失蹤了?我也不完全確定這是否會最終解除分塊,但這是另一回事。

__block NSUInteger i = 0; 
__block dispatch_block_t obtainBlock; 

obtainBlock = [^{ 
    [self obtainAssetAtIndex:i]; 
    progressView.progress += progressPerFile; 
    i++; 
    if (i < assets.count) { 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 
      usleep(500); 
      dispatch_async(dispatch_get_main_queue(), obtainBlock); 
     }); 
    } else { 
     [self didImportGroup]; 
     [obtainBlock release]; 
    } 
} copy]; 

dispatch_async(dispatch_get_main_queue(), obtainBlock); 
+0

您需要在'else'子句中設置'obtainBlock = nil'來釋放塊。爲什麼你需要在主線程上進行消耗? – 2012-07-26 17:32:25

+0

爲什麼我需要將它設置爲零?它在最後一次調用該塊時發佈。 – Kalle 2012-07-26 19:01:55

+0

你說得對。我錯過了。 – 2012-07-26 20:04:58

回答

3

想法太複雜了。當前設置:

  1. 做一件工作
  2. 手控制權交給後臺線程
  3. 睡背景
  4. 安排下一項工作在主線程上

要什麼做:

  1. 做一件作品
  2. 安排下一項工作

這裏是代碼:

- (void)doWork 
{ 
    if (_assetIndex < assets.count) { 
     [self obtainAssetAtIndex:_assetIndex++]; 
     progressView.progress += progressPerFile; 
     [self performSelector:@selector(doWork) withObject:nil afterDelay:0]; 
    } else { 
     [self didImportGroup]; 
    } 
} 

你不都需要一個後臺線程(尤其是當所有以往任何時候做的事情是睡覺)。

+0

*呻吟*謝謝。我不知道我在想什麼。很明顯,你就是這麼做的。 – Kalle 2012-07-26 19:09:33