等待两个异步方法完成

时间:2014-02-16 21:23:49

标签: objective-c ios7

我想初始化一个模型,让模型做一些异步的东西,并在完成后呈现一个新的viewcontroller。但是,我如何等待两个异步方法完成,如何设置回调方法?

伪代码

在我的StartViewController.m中:

-(void)openArticle
{
  article = [Article initWithObject:someObject];
  article.callback = changeView;
}

-(void)changeView
{
 [self presentViewController:someController];
}

在我的ArticleModel.m中:

-(void)initWithObject:someObject
{
  [self loadImage]
  [self geoCode]
}

-(void)loadImage
{
  runAsyncMethod: success:^()  // This one is actually a AFNetworking setImageWithURLRequest
}

-(void)geoCode
{
  runAnotherAsyncMethod: success:^() // This one is actually a geocodeAddressString operation
}

4 个答案:

答案 0 :(得分:3)

您可以使用dispatch_group s

来实现此目的
- (void)initWithObject:(id)someObject
{
  self = [super init];
  if (self) {
    self.dispatch_group = dispatch_group_create();

    [self loadImage]
    [self geoCode]

    dispatch_group_notify(self.dispatch_group, dispatch_get_main_queue(), ^{
      NSLog(@"Push new view controller");
    });
  }
  return self;
}

- (void)loadImage
{
  dispatch_group_enter(self.dispatch_group);

  __weak __typeof(self) weakSelf = self;
  runAsyncMethod: success:^{
    __typeof(weakSelf) strongSelf = weakSelf;
    if (strongSelf.dispatch_group) {
      dispatch_group_leave(strongSelf.dispatch_group); // You need to ensure that this is called in both success and failure
    }
  }

}

- (void)geoCode
{
  dispatch_group_enter(self.dispatch_group);

  __weak __typeof(self) weakSelf = self;
  runAnotherAsyncMethod: success:^{
    __typeof(weakSelf) strongSelf = weakSelf;
    if (strongSelf.dispatch_group) {
      dispatch_group_leave(strongSelf.dispatch_group);
    }
  }
}

答案 1 :(得分:1)

等待。如果你等,它不是异步的!如果你要等待,你将失去整个异步点。

你所做的是,当你的success处理程序被调用时,你走出主线程(以防你在后台线程上回调),现在做你需要做的事情。换句话说,只要碰到被调用,就让你的success处理程序被调用。

在您的情况下,您可能想要链接您想要做的事情:

  • 致电loadImage

  • 在回调中,请致电geoCode

  • 在其回调中,转到主线程并显示新的视图控制器。

答案 2 :(得分:1)

您可以使用dispatch_group,这样当方法结束时,它就会离开组。我自己使用类似的代码,它就像一个魅力。

- (void)initWithObject:someObject {

    // Create a dispatch group
    dispatch_group_t group = dispatch_group_create();
    [self loadImageWithDispatchGroup:group];
    [self geoCodeWithDispatchGroup:group];

    // Here we wait for all the requests to finish
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        // Do whatever you need to do when all requests are finished
    });
}

- (void)loadImageWithDispatchGroup:(dispatch_group_t)group {
    dispatch_group_enter(group);
     runAsyncMethod: success:^()  // This one is actually a AFNetworking setImageWithURLRequest
    // In your success or failure AFNetworking method, call this as soon as the request ended
    dispatch_group_leave(group);
}

- (void)geoCodeWithDispatchGroup:(dispatch_group_t)group {
    dispatch_group_enter(group);
    runAnotherAsyncMethod: success:^() // This one is actually a geocodeAddressString operation
    // In your success async geocode callback method, call this as soon as the request ended
    dispatch_group_leave(group);
}

答案 3 :(得分:0)

我不知道您的需求,但是本机GCD方式等待几个异步任务是

void dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);

https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/c/func/dispatch_barrier_async