美文网首页iOS Developer程序员小知识点
多个网络请求同时进行的问题

多个网络请求同时进行的问题

作者: 白极翁 | 来源:发表于2017-01-04 16:43 被阅读176次

    当有三个网络请求时a、b、c,这三个请求同时发生时,当我要获得请求后的数据时,该怎么解决

    常见的解决方法有两种
    1. 通过添加标识符来判断请求是否全部结束
    2. 通过dispatch_group + 信号量

    通过dispatch_group + 信号量来处理

    /**创建信号量*/
    dispatch_semaphore_t   semaphore = dispatch_semaphore_create(0);
    /**创建全局并行*/
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
    dispatch_queue_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
       NSLog(@"处理事件A"); 
       for (int i = 0; i<10000; i++) {
           NSLog(@"打印i %d",i); 
        } 
        dispatch_semaphore_signal(semaphore); 
        }); 
        dispatch_group_async(group, queue, ^{ 
        NSLog(@"处理事件B"); 
        for (int i = 0; i<10000; i++) { 
        NSLog(@"打印j %d",i);
         } 
        dispatch_semaphore_signal(semaphore); 
        });
         dispatch_group_async(group, queue, ^{
         NSLog(@"处理事件C");
         for (int i = 0; i<10000; i++) { 
        NSLog(@"打印k %d",i);
         } 
        dispatch_semaphore_signal(semaphore); }); 
        dispatch_group_async(group, queue, ^{ 
        NSLog(@"处理事件D"); 
        for (int i = 0; i<10000; i++) {
         NSLog(@"打印l %d",i); 
        } 
        dispatch_semaphore_signal(semaphore);
         });
    
      dispatch_group_notify(group,queue, ^{
          //四个请求对应四次信号等待
          dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
          dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
          dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
          dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
          NSLog(@"处理事件E");
    });
    
    分析:

    首先创建并行队列,创建队列组,将队列和需要处理的网络请求分别添加到组中,当组中所有队列处理完事件后调用dispatch_group_notify,我们需要在里面处理事件E。由于队列在处理网络请求时将“发送完一个请求”作为事件完成的标记(此时还未获得网络返回的数据),所以在这里需要信号量进行控制,在执行dispatch_group_notify前发起信号等待(4次信号等待,分别对应每个队列的型号通知),在每个队列获取到网络请求返回数据时发出信号通知。这样就能完成需求中的要求。
    如果需求中改为:同时存在A,B,C,D四个任务,要求ABCD依次进行处理,当上一个完成时在进行下一个任务,当四个任务都完成时在处理事件E,这是只需要将队列改为串行队列即可(不在需要信号控制)

    下面采用dispatch_group_enter、dispatch_group_leave实现

    -  (void)loadRequest1
    {
        dispatch_group_t dispatchGroup = dispatch_group_create();
        dispatch_group_enter(dispatchGroup);
        [WXDataService requestURL:url httpMethod:@"GET" params:nil completion:^(id         result) {
                UIImage * image = [UIImage imageWithData:result];
                [_imageArray replaceObjectAtIndex:i withObject:image];
                
                dispatch_group_leave(group);
            } failure:^(NSError *error) {
                
                NSLog(@"%@",error);
            }];
        }
        
        //当网络请求全部完成后,会调用这个方法来通知主线程更新UI
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
           
            for (int i = 0; i < _imageArray.count; i++) {
                _expertImageView = [self.contentView viewWithTag:20+i];
                _expertImageView.image = _imageArray[i];
            }
            
        });
    }
    

    相关文章

      网友评论

        本文标题:多个网络请求同时进行的问题

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