Swift:异步任务+完成处理

5

我在Swift中遇到了许多关于异步任务的困惑。我想要做的是像这样的事情...

 func buttonPressed(button: UIButton) {
   // display an "animation" tell the user that it is calculating (do not want to freeze the screen
   // do some calculations (take very long time) at the background
   // the calculations result are needed to update the UI
 }

我尝试做类似这样的事情:
func buttonPressed(button: UIButton) {
    let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
    dispatch_async(queue) { () -> Void in
       // display the animation of "updating"
       // do the math here
        dispatch_async(dispatch_get_main_queue(), {
          // update the UI
       }
    }
}

然而,我发现界面在等待我的计算完成之前已经更新了。我对异步队列的使用感到困惑。有人能帮忙吗?谢谢。

“// do the math here” 是否会向服务器发出请求? - bbarnhart
不,只是进行很多计算,需要相当长的时间,我不想让屏幕冻结... :( - user6539552
2个回答

9
你需要一个带有异步完成处理程序的函数。
在计算结束时调用 completion()
func doLongCalculation(completion: () -> ())
{
  // do something which takes a long time
  completion()
}

buttonPressed函数中,将calculate函数分派到后台线程上执行,完成后再回到主线程更新UI。
func buttonPressed(button: UIButton) {
  // display the animation of "updating"
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {  
    self.doLongCalculation {
      dispatch_async(dispatch_get_main_queue()) {
        // update the UI
        print("completed")
      }
    }
  }
}

0
dispatch_queue_t dispatchqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(dispatchqueue, ^(void){
    while ([self calculate]) {
        NSLog(@"calculation finished");
        dispatch_async(dispatch_get_main_queue(), ^{
            // update the UI
        });
    }
});

- (BOOL)calculate
{
    //do calculation
    //return true or false based on calculation success or failure
    return true;
}

2
等待是一种相当糟糕的方式。 - vadian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接