在Objective-C中触发异步回调的更好方法

时间:2012-08-27 11:18:52

标签: objective-c ios5 grand-central-dispatch nsnotifications

如果可能的话,我正在寻找更好的方法。

我有一个异步回调来更新本地sqlite数据库。更新完成后,我在单例变量(archiveUpdateComplete)中设置了一个标志。我一直睡到标志设置为真,然后我保持我的tableview。想删除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];

      });



  });

}

2 个答案:

答案 0 :(得分:3)

如果您需要推荐

轮询/睡觉很少是必要或不好的。作为替代方案:

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

如果您不需要推荐

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

  • 如果您的经理知道完成后要向谁发送消息,那么经理可以简单地给它发消息。如果必须在主线程上发生,则可以使用-[NSObject performSelectorOnMainThread:withObject:waitUntilDone:]转发到主线程。您也可以与代表一起看到这种方法。在单身人士的情况下,采取这种方式并没有多大意义。

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

  • Key Value Observing(KVO)是另一种选择。

答案 1 :(得分:0)

也许我错过了什么,但你为什么不直接使用完成回调?

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

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