我想初始化一个模型,让模型做一些异步的东西,并在完成后呈现一个新的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
}
答案 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);