GCD組函數(shù)的使用
使用場(chǎng)景:在開發(fā)中遇到過這樣的功能,某個(gè)界面列表上面是資源信息造烁,下面是評(píng)論列表信息欺嗤,而且資源信息和評(píng)論列表信息不是同一個(gè)接口,必須等兩者數(shù)據(jù)都獲取完畢的時(shí)候才能刷新UI
1综苔、dispatch_group_t和dispatch_group_async
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 1、
dispatch_group_async(group, queue, ^{
[NetworkTool postAlloc:@"http://www.reibang.com/" parameters:nil successed:^(id json) {
NSLog(@"http://www.reibang.com/ --- success");
} failure:^(NSError *error) {
NSLog(@"http://www.reibang.com/ --- failure");
}];
});
// 2位岔、
dispatch_group_async(group, queue, ^{
[NetworkTool postAlloc:@"https://www.baidu.com/" parameters:nil successed:^(id json) {
NSLog(@"https://www.baidu.com/ --- success");
} failure:^(NSError *error) {
NSLog(@"https://www.baidu.com/ --- failure");
}];
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"dispatch_group_notify --- 結(jié)束");
});
輸出結(jié)果
[ViewController.m:278行] dispatch_group_notify --- 結(jié)束
[ViewController.m:264行] http://www.reibang.com/ --- failure
[ViewController.m:271行] https://www.baidu.com/ --- success
說明:這時(shí)候問題來了如筛, [NetworkTool postAlloc:parameters:successed:failure]這是封裝的請(qǐng)求方法(異步函數(shù)),大家都知道抒抬,異步函數(shù)不會(huì)阻塞主線程杨刨,不等異步函數(shù)執(zhí)行完畢,dispatch_group_notify里的代碼就開始執(zhí)行了擦剑。
解決方法:請(qǐng)看下面的2妖胀、和3、實(shí)現(xiàn)惠勒。
2赚抡、dispatch_group_enter和dispatch_group_leave
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[NetworkTool postAlloc:@"http://www.reibang.com/" parameters:nil successed:^(id json) {
dispatch_group_leave(group);
NSLog(@"http://www.reibang.com/ --- success");
} failure:^(NSError *error) {
dispatch_group_leave(group);
NSLog(@"http://www.reibang.com/ --- failure");
}];
dispatch_group_enter(group);
[NetworkTool postAlloc:@"https://www.baidu.com/" parameters:nil successed:^(id json) {
dispatch_group_leave(group);
NSLog(@"https://www.baidu.com/ --- success");
} failure:^(NSError *error) {
dispatch_group_leave(group);
NSLog(@"https://www.baidu.com/ --- failure");
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"dispatch_group_notify --- 結(jié)束");
});
輸出結(jié)果
[ViewController.m:233行] http://www.reibang.com/ --- failure
[ViewController.m:239行] https://www.baidu.com/ --- success
[ViewController.m:246行] dispatch_group_notify --- 結(jié)束
3、dispatch_group_t纠屋、dispatch_group_async和dispatch_semaphore_t結(jié)合實(shí)現(xiàn)
//使用GCD的信號(hào)量 dispatch_semaphore_t 創(chuàng)建同步請(qǐng)求
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 1涂臣、
dispatch_group_async(group, queue, ^{
dispatch_semaphore_t semaphore= dispatch_semaphore_create(0);
//模擬網(wǎng)絡(luò)多線程耗時(shí)操作
dispatch_group_async(group, queue, ^{
sleep(5);
NSLog(@"%@-->線程1結(jié)束。售担。赁遗。",[NSThread currentThread]);
dispatch_semaphore_signal(semaphore);
});
NSLog(@"%@-->1結(jié)束闯估。。吼和。",[NSThread currentThread]);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
// 2涨薪、
dispatch_group_async(group, queue, ^{
dispatch_semaphore_t semaphore= dispatch_semaphore_create(0);
//模擬網(wǎng)絡(luò)多線程耗時(shí)操作
dispatch_group_async(group, queue, ^{
sleep(3);
NSLog(@"%@-->線程2結(jié)束。炫乓。刚夺。",[NSThread currentThread]);
dispatch_semaphore_signal(semaphore);
});
NSLog(@"%@-->2結(jié)束。末捣。侠姑。",[NSThread currentThread]);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
dispatch_group_notify(group, queue, ^{
NSLog(@"%@-->全部結(jié)束。箩做。莽红。",[NSThread currentThread]);
});
dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"%@---全部結(jié)束。邦邦。安吁。",[NSThread currentThread]);
});
輸出結(jié)果
[ViewController.m:197行] <NSThread: 0x6000000755c0>{number = 6, name = (null)}-->1結(jié)束。燃辖。鬼店。
[ViewController.m:212行] <NSThread: 0x61000007f6c0>{number = 7, name = (null)}-->2結(jié)束。黔龟。妇智。
[ViewController.m:208行] <NSThread: 0x608000274dc0>{number = 10, name = (null)}-->線程2結(jié)束。氏身。巍棱。
[ViewController.m:194行] <NSThread: 0x600000264f40>{number = 11, name = (null)}-->線程1結(jié)束。蛋欣。航徙。
[ViewController.m:217行] <NSThread: 0x6000000755c0>{number = 6, name = (null)}-->全部結(jié)束。豁状。捉偏。
其他的實(shí)現(xiàn)方法有(OSSpinLock 倒得、pthread_mutex_t泻红、NSLock等):
#import <libkern/OSAtomic.h>
//#import <pthread.h>
__block OSSpinLock spinLock = OS_SPINLOCK_INIT;
//__block pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
//NSLock *lock = [NSLock new];
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 1、
dispatch_group_async(group, queue, ^{
//模擬網(wǎng)絡(luò)多線程耗時(shí)操作
OSSpinLockLock(&spinLock);
//pthread_mutex_lock(&mutex);
//[lock lock];
dispatch_group_async(group, queue, ^{
sleep(5);
NSLog(@"%@-->線程1結(jié)束霞掺。谊路。。",[NSThread currentThread]);
});
NSLog(@"%@-->1結(jié)束菩彬。缠劝。潮梯。",[NSThread currentThread]);
OSSpinLockUnlock(&spinLock);
//pthread_mutex_unlock(&mutex);
//[lock unlock];
});
// 2、
dispatch_group_async(group, queue, ^{
OSSpinLockLock(&spinLock);
//模擬網(wǎng)絡(luò)多線程耗時(shí)操作
dispatch_group_async(group, queue, ^{
sleep(3);
NSLog(@"%@-->線程2結(jié)束惨恭。秉馏。。",[NSThread currentThread]);
});
NSLog(@"%@-->2結(jié)束脱羡。萝究。。",[NSThread currentThread]);
OSSpinLockUnlock(&spinLock);
});
dispatch_group_notify(group, queue, ^{
NSLog(@"%@-->全部結(jié)束锉罐。帆竹。。",[NSThread currentThread]);
});