GCD信号量的线程同步实际应用

2021-12-13  本文已影响0人  dalu

我们在APP开发过程中经常会遇到 :一个 APP 页面需要同时请求多个接口都完成后再刷新界面。

GCD的队列组dispatch_group是一个常用的解决方案。
当然还有其它方案,本文不做讨论。

dispatch_group_t group = dispatch_group_create();
//创建并行队列
dispatch_queue_t conQueue = dispatch_queue_create("com.selectCorrentNetsAsys", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_async(group, conQueue, ^{
    //网络A请求
});
dispatch_group_async(group, conQueue, ^{
    //网络B请求
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    //更新UI
});

这段代码恐怕大家都看烂了,为什么还要写一篇小文呢,别急!

实际应用中出现的问题:
网络请求在App中是封装好的,都是异步请求。会出现数据请求还没有完成,迅速就执行了dispatch_group_notify更新UI了。
如何解决这种情况?(核心内容)
把异步网络请求操作改成同步请求,信号量dispatch_semaphore就是合适人选🤠。

dispatch_semaphore_t signal = dispatch_semaphore_create(0);
dispatch_group_t group = dispatch_group_create();
//创建并行队列
dispatch_queue_t conQueue = dispatch_queue_create("com.selectCorrentNetsAsys", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_async(group, conQueue, ^{
    //网络A请求
    [LoginRequest doPingWithIP:@"www.baiduA.com" finishBlock:^(BOOL isok) {
        if (isok) {
            
        }
        dispatch_semaphore_signal(signal);
    }];
    dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
});
dispatch_group_async(group, conQueue, ^{
    //网络B请求
    [LoginRequest doPingWithIP:@"www.baiduB.com" finishBlock:^(BOOL isok) {
        if (isok) {
            
        }
        dispatch_semaphore_signal(signal);
    }];
    dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    //更新UI
});

注意:有些人的网络请求是成功和失败分开的两个block,记得都要执行dispatch_semaphore_signal(signal)哦!

上一篇下一篇

猜你喜欢

热点阅读