美文网首页零碎知识点iOS_swiftiOS Developer
GCD在AFN中等待多个请求完成执行下个请求

GCD在AFN中等待多个请求完成执行下个请求

作者: 动机至善私心了无 | 来源:发表于2016-11-15 16:01 被阅读1815次

有六个请求,前五个请求为异步请求,而第六个请求需要拿到前五个请求的数据再执行. 本来这种请求按照书上写的这种形式就可以.如:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^{
        dispatch_group_t group = dispatch_group_create();
        
        dispatch_group_async(group, queue, ^{
            [self onePositiveImageUpload:self.positiveImageView.image];
        });
        dispatch_group_async(group, queue, ^{
            [self oneReverseImageUpload:self.reverseImageView.image];
        });
        dispatch_group_async(group, queue, ^{
            [self moreFirstImageUploadWithArray:self.houseCardArray];
        });
        dispatch_group_async(group, queue, ^{
            [self moreSecondImageUploadWithArray:self.leaseArray];
        });
        dispatch_group_async(group, queue, ^{
            [self moreThirdImageUploadWithArray:self.applicantArray];
        });
        
//等待上面请求完成之后再执行里面的步骤
        dispatch_group_notify(group, queue, ^{
            [self requestSaveHouseMaterial];
        });
    });

但是项目中我们一般都是使用AFN请求,此时再使用这种格式就不可以了.会造成最后一个请求开始时拿到的没有拿到前几个请求完成之后的数据.此时就可以使用这种方法了

创建一个全局的group
dispatch_group_t _group;

在前几个请求中都加入 dispatch_group_enter(_group); 成功或失败时加入dispatch_group_leave(_group); 如:
dispatch_group_enter(_group);
    AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
    mgr.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html", nil];
    // 2.封装参数(这个字典只能放非文件参数)
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    // 2.发送一个请求
    [mgr POST:UPLOAD_IMAGE_URL parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        NSMutableArray *arr = [NSMutableArray array];
        for (int i = 0; i < array.count; i ++)
        {
            NSData *fileData = UIImageJPEGRepresentation(array[i], 0.05);
            [arr addObject:fileData];
        }
        for (int i = 0; i < arr.count; i ++)
        {
            [formData appendPartWithFileData:arr[i] name:[NSString stringWithFormat:@"filestream%d", i] fileName:[NSString stringWithFormat:@"zhengshu%d.jpg", i] mimeType:@"image/jpeg"];
        }
    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSMutableDictionary *data = responseObject[@"data"];
        // 图片数组
        NSArray *array = [data[@"fileName"] componentsSeparatedByString:@","];
        NSMutableArray *urlArr = [NSMutableArray array];
        for (int i = 0; i < array.count; i ++)
        {
            NSString *url = [array[i] lastPathComponent];
            [urlArr addObject:url];
        }
        self.thirdString = [urlArr componentsJoinedByString:@","];
        dispatch_group_leave(_group);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        [SMGlobalMethod showMessage:NetNoti];
        dispatch_group_leave(_group);
    }];

请求的时候这样写就OK了.
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^{
        _group = dispatch_group_create();
        
        dispatch_group_async(_group, queue, ^{
            [self onePositiveImageUpload:self.positiveImageView.image];
        });
        dispatch_group_async(_group, queue, ^{
            [self oneReverseImageUpload:self.reverseImageView.image];
        });
        dispatch_group_async(_group, queue, ^{
            [self moreFirstImageUploadWithArray:self.houseCardArray];
        });
        dispatch_group_async(_group, queue, ^{
            [self moreSecondImageUploadWithArray:self.leaseArray];
        });
        dispatch_group_async(_group, queue, ^{
            [self moreThirdImageUploadWithArray:self.applicantArray];
        });
        
        //因上面请求中有加入dispatch_group_enter 和 dispatch_group_leave,所以真正等待上面线程执行完才执行这里面的请求
        dispatch_group_notify(_group, queue, ^{
            [self requestSaveHouseMaterial];
        });
    });
这样我们使用AFN请求数据的时候,就真正做到了等待多个请求完成再执行下一个请求

因为上面是在项目中遇到的问题,所以只是粗略的写了一下,中午的时候写了一份Demo.(正好又学习了一下GitHub使用,原来从来没往上面提交过代码....).和上面的代码不一样.列举了三种不同的方式,助于大家分辨.有想看的可以去看看

相关文章

网友评论

  • 我是李文艺:为啥最外层还要用一层 dispatch_async(queue, ^{});这个方法 我不是很理解 您能给解释一下吗?
    动机至善私心了无:@我是李文艺 这里的dispatch_async(queue, ^{});是开启一个异步队列. 不过这个方法确实多余了.谢谢指导
    我是李文艺:我是觉得楼主最外层的这个方法有点儿多余了 不知道它的意义在哪儿
  • 知交:群,直到今天,我终于用上了你这篇文章:kissing_heart:
  • KODIE:对了,这个如果要是要做AFN的依赖呢怎么做,我的意思是多个依赖问题,我这边测试试不OK的,求教,在线等!!!
    好棒大大:我的afn是for循环 调用的 你的方法不ok的 求解
    动机至善私心了无:@KODIE 下面有Demo的,Demo中有就是这样写的,请求开始dispatch_group_enter(_group),结束之后在出去,做AFN的依赖也是一样的道理
  • b1e1452d05fa:请教个问题,在gcd里使用afn多任务下载功能时,需要实时回调每个下载任务的下载进度。这个怎么实现比较好
    动机至善私心了无:@MrZwT KVO监听或者通知,多任务下载没怎么涉及到过
  • 蔡少:这样改的原理是怎么回事啊?能否解释下
    动机至善私心了无: @蔡少 @动机至善私心了无 leave就是代表离开的意思,所以在请求成功和失败后都写了leave
    动机至善私心了无: @蔡少 这就相当于把这个全局的GCD加到一个组中,enter就是代表进入的意思。只有在请求完成或者失败才能出来。而最后的notify则是监听加入到组中的所有请求是否完成。完成后则进行里面的内容
  • 終點起點:这个有些地方很实用
    动机至善私心了无: @終點起點 😁实用就好
  • iOS_er:不错,老哥写的很稳,一看就明白。
    动机至善私心了无:@iOS_er 😀,谢谢
  • nenhall:有没demo 一起贡献上
    nenhall:@动机至善私心了无 好人啊:+1::+1::+1:
    动机至善私心了无:OK,文章的最后有Demo的地址.
    动机至善私心了无:@NegHao 实在对不住, Demo还真没有.这是项目中的代码.抱歉了,有时间的话我写一份Demo吧.

本文标题:GCD在AFN中等待多个请求完成执行下个请求

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