美文网首页
多线程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