前言:
常常遇到一个页面有多个请求,这些请求当中缺存在某些依赖关系的情况,鉴于网络请求当中,大多属于异步请求,无法及时得到我们想要的数据。于是需要用到一些方法,使异步请求执行同步操作。
方法一:使用GCD串行队列
首先要搞清楚在队列当中,有串行和并行
// DISPATCH_QUEUE_CONCURRENT + async 开启多条线程
// DISPATCH_QUEUE_SERIAL + async 不开启多条线程
dispatch_queue_t queue = dispatch_queue_create("my queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
for (int i=0; i<5; i++) {
NSLog(@"task-1---%d---%@",i,[NSThread currentThread]);
sleep(1.0);
}
});
dispatch_async(queue, ^{
for (int i=0; i<5; i++) {
NSLog(@"task-2---%d---%@",i,[NSThread currentThread]);
sleep(1.0);
}
});
dispatch_async(queue, ^{
for (int i=0; i<5; i++) {
NSLog(@"task-3---%d---%@",i,[NSThread currentThread]);
sleep(1.0);
}
});
看看打印结果,执行完task-1后,依次执行task-2,再执行了task-3
方法二:barrier GCD
dispatch_queue_t queue = dispatch_queue_create("my concurrent queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_suspend(queue);// 挂起
dispatch_async(queue, ^{
[self loadDataA:^(BOOL success) {
NSLog(@" A 加载完成");
}];
});
dispatch_barrier_async(queue, ^{
NSLog(@"--this is a barrier--");
});
dispatch_async(queue, ^{
[self loadDataB:^(BOOL success) {
NSLog(@" B 加载完成");
}];
});
dispatch_resume(queue);// 恢复
方法三:dispatch_group_enter + dispatch_group_leave
注意:dispatch_group_enter() 和 dispatch_group_leave() 一定是配套使用的
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[self loadDataA:^(BOOL success) {
if (success) {
NSLog(@"A load finished...");
dispatch_group_leave(group);
}else {
finished(NO);
}
}];
dispatch_group_enter(group);
[self loadDataB:^(BOOL success) {
if (success) {
NSLog(@"B load finished...");
dispatch_group_leave(group);
}else {
finished(NO);
}
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
finished(YES);
NSLog(@"全部加载完成。。。%@",[NSThread currentThread]);
});
方法四:NSOperation 设置依赖关系
NSOperationQueue *operarionQueue = [[NSOperationQueue alloc]init];
NSBlockOperation *lastOperation = [NSBlockOperation blockOperationWithBlock:^{
sleep(1.0);
NSLog(@"最后的任务!");
}];
[operarionQueue addOperation:lastOperation];
for (int i=0; i<4; i++) {
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
sleep(i);
NSLog(@"任务%d",i+1);
}];
if (i==2) {
[operation addDependency:lastOperation];
}
[operarionQueue addOperation:operation];
}
if (i==2) {
[operation addDependency:lastOperation];
}
将lastOperation依赖于operation2执行,所以只有任务2执行完成,才会执行lastOperation
本文仅个人理解,欢迎指正和补充。。。觉得有用的可以点个赞哈!