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