项目用的
_group = dispatch_group_create();
//网络请求1
dispatch_group_enter(_group);
[weakSelf 网络请求1];
//网络请求2
dispatch_group_enter(_group);
[weakSelf 网络请求2];
//回到主线程刷新UI
dispatch_group_notify(_group, dispatch_get_main_queue(), ^{
}
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
[weakSelf requestDataOne:group];
});
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
[weakSelf requestDataTwo:group];
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[UIFactory dismissHUD];
if (weakSelf.errorInfo) {
//提示语
weakSelf.errorInfo = nil;
return;
}
[weakSelf.tableView reloadData];
});
无序网络请求,异步+并发
因为在dispatch_group_async()里使用dispatch_async()方法,dispatch_group_notify不是在最后执行的。所以要加dispatch_group_enter和dispatch_group_leave,等待上面的任务全部完成后,会收到通知执行dispatch_group_notify中的代码。
dispatch_group_enter和dispatch_group_leave和内存管理的引用计数类似,当调用enter时计数加1,调用leave时计数减1,当计数为0时会调用dispatch_group_notify并且dispatch_group_wait会停止等待
借鉴深入理解GCD之dispatch_group:https://www.jianshu.com/p/e93fd15d93d3
几个网络请求全部完成再进行页面渲染https://blog.csdn.net/xingjie1006/article/details/51443234
#import "ViewController.h"
@interface ViewController ()
{
dispatch_group_t _group;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.orangeColor;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
self.group = dispatch_group_create();
//第一个网络请求
dispatch_group_enter(self.group);
dispatch_group_async(self.group, queue, ^{
NSLog(@"group1--------%@",[NSThread currentThread]);
[self test1];
});
//第二个网络请求
dispatch_group_enter(self.group);
dispatch_group_async(self.group, queue, ^{
NSLog(@"group2--------%@",[NSThread currentThread]);
[self test2];
});
//第三个网络请求
dispatch_group_enter(self.group);
dispatch_group_async(self.group, queue, ^{
NSLog(@"group3--------%@",[NSThread currentThread]);
[self test3];
});
dispatch_group_notify(self.group, dispatch_get_main_queue(), ^{
NSLog(@"updateUi");
});
}
-(void)test1{
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.baidu.com"]];
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"第一步网络请求完成");
dispatch_group_leave(self.group);
}];
[task resume];
}
-(void)test2{
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.jisilu.cn"]];
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"第二步网络请求完成");
dispatch_group_leave(self.group);
}];
[task resume];
}
-(void)test3{
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.hao123.com"]];
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"第三步网络请求完成");
dispatch_group_leave(self.group);
}];
[task resume];
}
@end
2021-04-02 16:20:35.890739+0800 wertyu[18306:3215981] group1--------<NSThread: 0x28164c440>{number = 6, name = (null)}
2021-04-02 16:20:35.890778+0800 wertyu[18306:3215945] group2--------<NSThread: 0x2816401c0>{number = 7, name = (null)}
2021-04-02 16:20:35.890843+0800 wertyu[18306:3215982] group3--------<NSThread: 0x281644440>{number = 8, name = (null)}
2021-04-02 16:20:36.562078+0800 wertyu[18306:3215983] 第一步网络请求完成
2021-04-02 16:20:36.756025+0800 wertyu[18306:3215982] 第二步网络请求完成
2021-04-02 16:20:37.358324+0800 wertyu[18306:3215981] 第三步网络请求完成
2021-04-02 16:20:37.358680+0800 wertyu[18306:3215930] updateUi
有序网络请求,
#import "ViewController.h"
#import "TableViewController.h"
@interface ViewController ()
{
dispatch_semaphore_t semaphore;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.orangeColor;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
self.semaphore = dispatch_semaphore_create(0);
//第一个网络请求
dispatch_group_async(group, queue, ^{
NSLog(@"group1--------%@",[NSThread currentThread]);
[self test1];
});
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
//第二个网络请求
dispatch_group_async(group, queue, ^{
NSLog(@"group2--------%@",[NSThread currentThread]);
[self test2];
});
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
//第三个网络请求
dispatch_group_async(group, queue, ^{
NSLog(@"group3--------%@",[NSThread currentThread]);
[self test3];
});
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"updateUi");
});
}
-(void)test1{
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.jisilu.cn"]];
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"第一步网络请求完成");
dispatch_semaphore_signal(self.semaphore);
}];
[task resume];
}
-(void)test2{
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.baidu.com"]];
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"第二步网络请求完成");
dispatch_semaphore_signal(self.semaphore);
}];
[task resume];
}
-(void)test3{
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.hao123.com"]];
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"第三步网络请求完成");
dispatch_semaphore_signal(self.semaphore);
}];
[task resume];
}
@end
2021-04-09 16:22:24.139827+0800 wertyu[2276:306933] group1--------<NSThread: 0x282b17140>{number = 4, name = (null)}
2021-04-09 16:22:24.808904+0800 wertyu[2276:306933] 第一步网络请求完成
2021-04-09 16:22:24.809619+0800 wertyu[2276:306933] group2--------<NSThread: 0x282b17140>{number = 4, name = (null)}
2021-04-09 16:22:25.085318+0800 wertyu[2276:306933] 第二步网络请求完成
2021-04-09 16:22:25.085569+0800 wertyu[2276:306933] group3--------<NSThread: 0x282b17140>{number = 4, name = (null)}
2021-04-09 16:22:25.547856+0800 wertyu[2276:306933] 第三步网络请求完成
2021-04-09 16:22:25.548695+0800 wertyu[2276:306915] updateUi
dispatch_semaphore_create:创建一个信号
dispatch_semaphore_signal:使某个信号的信号量+1
dispatch_semaphore_wait:这个函数会使传入的信号量dsema的值减1,
如果-dsema信号量的值大于0,该函数所处线程就继续执行下面的语句,并且将信号量的值减1。
如果-desema的值为0,那么这个函数就阻塞当前线程等待timeout
如果-等待期间没有获取到信号量或者信号量的值一直为0,那么等到timeout时,其所处线程自动执行其后语句。
正常的使用顺序是先降低然后再提高,这两个函数通常成对使用。
网友评论