http://www.jianshu.com/p/480d0c64d63c
http://www.jianshu.com/p/228403206664
使用GCD解决
虽然这样可以解决这个问题,但是看起来比较复杂,要写一个类继承自NSOperation。之前也了解过GCD,那么能否考虑是使用GCD的方式来解决呢?
GCD中有一个dispatch_group_t的API,使用dispatch_group_t可以监控一组block,dispatch_group_t会追踪组内的block的执行状态,当group中所有的block完成以后,可以使用dispatch_group_notify来执行一个额外的block。增加dispatch_group_t中block的数量有两种方式,一种是使用dispatch_group_async或者dispatch_group_sync后面添加block,另外一种是使用dispatch_group_enter和dispatch_group_leave组合来代表一个block的开始和结束。在这里我们需要使用dispatch_group_enter和dispatch_group_leave组合。
代码如下:
-
(void)gcdGroup{
NSString *url1 = @"http://www.baidu.com";
NSString *url2 = @"http://www.jianshu.com";
dispatch_group_t group = dispatch_group_create();dispatch_group_enter(group);
[self getHtmlOfUrl:url1 success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable response) {
NSLog(@"get data of %@ success",url1);
dispatch_group_leave(group);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"get html of %@ fail",url1);
dispatch_group_leave(group);
}];dispatch_group_enter(group);
[self getHtmlOfUrl:url2 success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable response) {
NSLog(@"get data of %@ success",url2);
dispatch_group_leave(group);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"get html of %@ fail",url2);
dispatch_group_leave(group);
}];dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"push to new controller after all data is ready!");
});
}
实际上dispatch_group_t代表了一个信号量,该信号量有一个初始值。当调用dispatch_group_enter时该信号量的值-1,而掉用dispatch_group_leave的时候信号量的值加1.让信号量的值等于初始值时,就会执行dispatch_group_notify中的block。有兴趣的可以自己尝试一下使用dispatch_group_async看能不能解决异步任务依赖的需求。我个人的实验结果是和第一个例子的结果是一样的。