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又有点不一样,上面的是循环执行,这个是控制单次的进程等待的方法。看需求采取固定的方式吧。
暂时就讲这么多吧,下次遇见了其他需求再多说点。