1

如果可能的话,我正在寻找一种更好的方法来做到这一点。

我有一个更新本地 sqlite 数据库的异步回调。更新完成时,我在单例变量 (archiveUpdateComplete) 中设置了一个标志。我睡一会儿,直到标志设置为真,然后我为我的表格视图补充水分。想删除 sleep()!感谢您的任何建议。

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)




- (void)viewDidLoad
{



  dispatch_async(kBgQueue, ^{

    //Hydrate word archive table view

       do {
             sleep(1.0);


           } while ([sharedManager archiveUpdateComplete]==NO);



      [self performSelectorOnMainThread:@selector(hydrateWordArchive) withObject:nil waitUntilDone:YES];


      //Run custom activity indicator
      dispatch_async(dispatch_get_main_queue(), ^{
        [MBProgressHUD hideHUDForView:self.view animated:YES];

      });



  });

}
4

2 回答 2

3

如果您需要投票

轮询/睡眠很少是必要的或好的。作为备选:

  • 您可以将一个附加NSTimer到主线程的运行循环。
  • 计时器调用可以测试的选择器[sharedManager archiveUpdateComplete]
  • 如果YES返回,则
    • 使计时器无效
    • 称呼[MBProgressHUD hideHUDForView:self.view animated:YES];

如果您不需要投票

有一些直接的选择。你选择哪一个取决于什么知道什么:

  • 如果您的经理知道在完成后向谁发送消息,则经理可以简单地向其发送消息。如果这必须发生在主线程上,您可以使用-[NSObject performSelectorOnMainThread:withObject:waitUntilDone:]它转发到主线程。您也可以在代表中看到这种方法。在单例的情况下,走这条路线没有多大意义。

  • 如果您的经理不知道谁对更改/完成感兴趣,您的经理可以NSNotification在任务完成后(在当前线程或从主线程)发布。

  • 键值观察(KVO) 是另一种选择。

于 2012-08-27T11:24:11.263 回答
0

也许我错过了一些东西,但你为什么不为此使用完成回调呢?

换句话说,您将计算更改为根据嵌套块“思考”。第一个异步块(在某个并发队列上)执行更新数据库的工作,当它完成后,它会分派另一个异步块(到同一个并发队列)来补充 tableview。最后,从块中,您 dispatch_async 主队列上的另一个块会更新 UI,因为这是唯一需要在主队列上执行的位。

换句话说,您想要链接异步操作,而不是轮询。请参阅 dispatch_async() 手册页的 COMPLETION CALLBACKS 部分。

于 2012-08-27T20:46:19.003 回答