美文网首页
iOS GCD之项目实战

iOS GCD之项目实战

作者: 不会写代码的尬先生 | 来源:发表于2019-06-19 21:23 被阅读0次

    实际开发中我们可能会遇到这种需求:等待某几个网络请求结束再进行后续操作,比如一个页面需要先请求三个接口,都拿到数据以后再去做页面的渲染。

    可能我们会想到用gcd的dispatch_group_t,再异步并发请求接口,最后notify处理,但运行结果并不是我们预想的那样,而是先打印了notifyblock里的内容,才打印两个网络请求的内容,这是因为网络请求本身就是异步的,此时group的notify并不会真正等到网络请求结束才去处理notify。

        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_group_t group = dispatch_group_create();
        dispatch_group_async(group, queue, ^{
            NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
            [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
                
            } successBlock:^(id data) {
                NSLog(@"请求一");
                
            } failureBlock:^(NSString *error) {
                
            }];
            
        });
        dispatch_group_async(group, queue, ^{
            
            NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
            
            [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
                
            } successBlock:^(id data) {
                NSLog(@"请求二");
                
            } failureBlock:^(NSString *error) {
                
            }];
        });
    
        dispatch_group_notify(group, queue, ^{
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"请求完成");
            });
        });
    
    打印结果:
    请求完成
    请求二或请求三(异步,不确定先后)
    

    介绍两种实现方式
    一是用 dispatch_group_enter和dispatch_group_leave在每次网络请求成对使用

        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_group_t group = dispatch_group_create();
        dispatch_group_enter(group);
        dispatch_group_async(group, queue, ^{
            NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
            [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
                
            } successBlock:^(id data) {
                NSLog(@"请求一");
                dispatch_group_leave(group);
                
            } failureBlock:^(NSString *error) {
                
            }];
            
        });
        dispatch_group_enter(group);
        
        dispatch_group_async(group, queue, ^{
            
            NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
            
            [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
                
            } successBlock:^(id data) {
                NSLog(@"请求二");
                dispatch_group_leave(group);
                
            } failureBlock:^(NSString *error) {
                
            }];
        });
        
        dispatch_group_notify(group, queue, ^{
            dispatch_async(dispatch_get_main_queue(), ^{
                
                NSLog(@"请求完成");
                
            });
        });
    打印顺序:
    先打印      请求二或请求一(异步乱序)
    最后打印  请求完成
    

    第二种是用dispatch_group_t加dispatch_semaphore_t信号量

        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        // 创建全局并行
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_group_t group = dispatch_group_create();
        dispatch_group_async(group, queue, ^{
            
            NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
            
            [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
                
            } successBlock:^(id data) {
                NSLog(@"请求一");
                dispatch_semaphore_signal(semaphore);
                
            } failureBlock:^(NSString *error) {
                
            }];
            
        });
        dispatch_group_async(group, queue, ^{
            
            NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys:@"121", @"id",nil];
            
            [CSNetWoring sendPostNetWorkWithUrl:SPORT_ORUN_RESOURCE parameters:param progressBlock:^(NSProgress *progress) {
                
            } successBlock:^(id data) {
                NSLog(@"请求二");
                dispatch_semaphore_signal(semaphore);
                
            } failureBlock:^(NSString *error) {
                
            }];
        });
        
        dispatch_group_notify(group, queue, ^{
            NSLog(@"请求三");
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            NSLog(@"请求四");
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"请求完成");
                
            });
        });
    打印顺序:
    
    请求三
    请求一和请求二乱序
    请求四
    请求完成
    
    

    dispatch_semaphore_wait会一直阻塞线程直到网络请求成功收到dispatch_semaphore_signal信号

    相关文章

      网友评论

          本文标题:iOS GCD之项目实战

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