美文网首页
iOS开发,同时发起多个请求的处理方式

iOS开发,同时发起多个请求的处理方式

作者: Arthur澪 | 来源:发表于2023-07-06 10:21 被阅读0次

    需求场景:如,A网络请求 和 B网络请求完成后,刷新界面。

    方案一:通过GCD的信号量semaphore

    - (void)twoRequest {
        // 创建 任务组
        dispatch_group_t group = dispatch_group_create();
        // 获取一个全局队列
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        // 创建 信号量
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        
        // 执行循序1
        dispatch_group_async(group, queue, ^{
            // 第一个请求
            [[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
                if (isSucceeded) {
                    // Todo
                } else {
                    // 异常处理
                }
                 // 执行顺序4/6
                dispatch_semaphore_signal(semaphore);
            }];
        });
    
        // 执行循序2
        dispatch_group_async(group, queue, ^{
            // 第二个请求
            [[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
                if (isSucceeded) {
                    // Todo
                } else {
                    // 异常处理
                }
                // 执行顺序4/6
                dispatch_semaphore_signal(semaphore);
            }];
        });
        
    
        dispatch_group_notify(group, queue, ^{
             // 执行循序3
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
             // 执行顺序5 
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
             // 执行顺序7 
            dispatch_async(dispatch_get_main_queue(), ^{  刷新界面 });   
       });
    
    }
    

    信号量可以用车库中的空闲车位来表示。当要往车库停车时,如果车库已满,则需等待(阻塞线程)。

    • 关于信号量的三个方法

    1.创建一个车库,value表示车库中空闲车位的数量

    dispatch_semaphore_create(long value);
    

    2.往车库里停一辆车,如果没有空车位,则一直会等待在车库外,等待时间为dispatch_time_t timeout,如果有空车位则停车,减少一个空车位

    dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
    

    3.从车库中开走一辆车,增加一个空闲车位

    dispatch_semaphore_signal(dispatch_semaphore_t dsema);
    
    • 关于任务组的三个方法

    1、函数dispatch_group_notify(group1, queue1,block);
    监听group组中任务的完成状态,当所有的任务都执行完后,触发block块,执行总结性处理。

    2、函数dispatch_group_wait(group1, DISPATCH_TIME_FOREVER)
    当前线程暂停,等待此函数上面的任务执行完成后,线程才继续执行。

    3、函数dispatch_group_async(group, queue, block);
    将block任务添加到queue队列,并被group组管理。

    方案二: dispatch_group_enter

    { 
        dispatch_group_t group = dispatch_group_create();
    
        dispatch_group_enter(group);  // 任务 + 1
        
        [[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
                if (isSucceeded) {
                    // Todo
                } else {
                    // 异常处理
                }
                dispatch_group_leave(group);  // 任务 - 1
        }];
              
        dispatch_group_enter(group);  // 任务 + 1
    
        [[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
                if (isSucceeded) {
                    // Todo
                } else {
                    // 异常处理
                }
                dispatch_group_leave(group);  // 任务 - 1
        }];
    
        dispatch_group_notify(group, dispatch_get_main_queue(), ^(){
            NSLog(@"Group End!");
        });
    
    }
    

    简单来说,就是 dispatch_group_enter会对 group 的内部计数 +1,dispatch_group_leave 会对 group 的内部计数 -1,就类似以前的 retainrelease方法。也就是维护了一个计数器。

    相关文章

      网友评论

          本文标题:iOS开发,同时发起多个请求的处理方式

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