美文网首页
多线程GCD

多线程GCD

作者: 阿龍飛 | 来源:发表于2021-04-02 15:12 被阅读0次

项目用的

    _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时,其所处线程自动执行其后语句。

正常的使用顺序是先降低然后再提高,这两个函数通常成对使用。


相关文章

网友评论

      本文标题:多线程GCD

      本文链接:https://www.haomeiwen.com/subject/ozufkltx.html