iOS - 信号量和GCD高级用法

一、前言

  我们开发的时候老是会遇到一个需求就是,需要多个网络请求成功后才开始刷新界面,这个时候我们就需要用到GCD 的 dispatch_group_t 方法。

  话不多说开始。

二、代码

  1、先创建对象

dispatch_group_t group = dispatch_group_create();

  2、循环执行网络请求


dispatch_group_enter(group);
for (int i = 0; i < self.seasonList.count; i++) {
        [NetRequest postWithBasicParameters:dict success:^(NSDictionary *arg) {
            //网络请求成功
            dispatch_group_leave(group);
        } failure:^(NSString *arg) {
            //网络请求失败
            dispatch_group_leave(group);
        }];
    }

  注:这里要注意的是无论是网络请求失败还是成功,都要调用结束方法,不然会阻塞线程。

  3、等所有循环结束后开始刷新UI

dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        asyncMainBlock(^{
            [EasyLodingView hidenLoding];
            //排序
            for (int i = 0; i < self.datasource.count ; i++) {
                for (int j = 0 ; j<self.datasource.count-1 ; j++) {
                    NSDictionary *dict_one = self.datasource[j];
                    NSInteger dict_oneNum = [[dict_one objectOrNilForKey:@"seaId"] integerValue];
                    
                    NSDictionary *dict_two = self.datasource[j+1];
                    NSInteger dict_twoNum = [[dict_two objectOrNilForKey:@"seaId"] integerValue];
                    
                    if (dict_oneNum > dict_twoNum) {
                        [self.datasource exchangeObjectAtIndex:j withObjectAtIndex:j+1];
                    }
                }
            }
            
            [self.listTableView reloadData];
        });
    });

  注:我这边为了数据展示正常需要进行一次冒泡排序,因为每个网络请求的快慢不一样。

三、信号量

  1、信号量是用于多线程同步的,跟锁不一样的是,信号量不一定是锁定某一个资源,而是流程上的概念,比如:有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务 并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类。

  而对于锁来说,锁住的资源无法被其余的线程访问,从而阻塞线程而实现线程同步。

  2、方法

//创建信号量,参数:信号量的初值,如果小于0则会返回NULL
dispatch_semaphore_create(信号量值)
 
//等待降低信号量
dispatch_semaphore_wait(信号量,等待时间)
 
//提高信号量
dispatch_semaphore_signal(信号量)

  3、举例

-(void)dispatchSignal{
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);   
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
     
    //任务1
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 1");
        sleep(1);
        NSLog(@"complete task 1");
        dispatch_semaphore_signal(semaphore);       
    });<br>
    //任务2
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 2");
        sleep(1);
        NSLog(@"complete task 2");
        dispatch_semaphore_signal(semaphore);       
    });<br>
    //任务3
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 3");
        sleep(1);
        NSLog(@"complete task 3");
        dispatch_semaphore_signal(semaphore);       
    });   
}

  注:这个和上面的GCD又有点不一样,上面的是循环执行,这个是控制单次的进程等待的方法。看需求采取固定的方式吧。

  暂时就讲这么多吧,下次遇见了其他需求再多说点。

 

posted on 2019-12-15 14:03  麦芽呀~  阅读(1972)  评论(0编辑  收藏  举报