dispatch_once
在dispatch_once block中的代码在程序启动到程序退回只会执行一次,如:不管for循环多少,只会一次打印
for (int i = 0; i<10; i++) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"----once--"); }); } 2017-09-02 14:53:13.085 GCD测试[11539:156889] ----once--
利用dispatch_once实现单粒模式
单粒模式(不管以任何方式创建对象,内存中永远只会有且仅有一份该对象的地址)
实现单粒,需要步骤: 1.提供一个类方法,用以返回该对象 2.实现类方法(使用dispatch_once限制只运行一次) 3.重写 + allocWithZone:(struct _NSZone *)zone(通过alloc时会最终会调用 + allocWithZone:(struct _NSZone *)zone,所以直接实现+ allocWithZone就好,使用dispatch_once限制只运行一次) 4.实现 - (id)copyWithZone:(NSZone *)zone
#ifndef Singleten_h #define Singleten_h #pragma mark - 实例定义 #define SingletenInterface(name) + (instancetype)shared##name; #pragma mark - 定义单例代码块 #define SingletenImpl(name) static id _instace; + (id)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instace = [super allocWithZone:zone]; }); return _instace; } - (id)copyWithZone:(NSZone *)zone { return _instace; } + (instancetype)shared##name { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instace = [[self alloc] init]; }); return _instace; } #endif /* Singleten_h */
此方式不能使用继承方式,要不然所有子类所有实例都是同一个
线程栏杆barrier
可以让栏杆前的任务先执行完,再执行栏杆后的任务,此处不要使用全局队列dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),经测试如果使用global,barrier栏杆效果没有.
dispatch_barrier_<a>sync: 作用:在它前面的任务执行结束后它才执行,在它后面的任务等它执行完成后才会执行 注意点:使用barrier时不要使用全局队列dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 如果是dispatch_barrier_<a>sync不能使用全局队列,经测试是不起作用的 dispatch_queue_t queue = dispatch_queue_create("HJiang", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ NSLog(@"1 %@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"2 %@",[NSThread currentThread]); }); dispatch_barrier_async(queue, ^{ NSLog(@"---------barrier %@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"3 %@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"4 %@",[NSThread currentThread]); }); 2017-09-01 17:56:40.893 GCD测试[9872:286531] 1 <NSThread: 0x608000070800>{number = 3, name = (null)} 2017-09-01 17:56:40.893 GCD测试[9872:286528] 2 <NSThread: 0x60000006f280>{number = 4, name = (null)} 2017-09-01 17:56:40.893 GCD测试[9872:286494] ---------barrier <NSThread: 0x608000063280>{number = 1, name = main} 2017-09-01 17:56:40.894 GCD测试[9872:286528] 3 <NSThread: 0x60000006f280>{number = 4, name = (null)} 2017-09-01 17:56:40.894 GCD测试[9872:286531] 4 <NSThread: 0x608000070800>{number = 3, name = (null)}
线程组
dispatch_group_create:创建线程组
dispatch_group_async:线程组异步任务
dispatch_group_notify:线程组任务所有完成后,通知执行方法
dispatch_group_wait:线程组等待,会阻塞当前线程,比较少用,特别是当前线程是主线程时,dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 5);
// dispatch_group_create() // dispatch_group_async(<#dispatch_group_t _Nonnull group#>, <#dispatch_queue_t _Nonnull queue#>, <#^(void)block#>) // dispatch_group_notify(<#dispatch_group_t _Nonnull group#>, <#dispatch_queue_t _Nonnull queue#>, <#^(void)block#>) // dispatch_group_wait(<#dispatch_group_t _Nonnull group#>, <#dispatch_time_t timeout#>) // dispatch_group_enter(<#dispatch_group_t _Nonnull group#>) // dispatch_group_leave(<#dispatch_group_t _Nonnull group#>) dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_queue_create("HJiang", DISPATCH_QUEUE_CONCURRENT); dispatch_group_async(group, queue, ^{ for (int i = 0; i<5; i++) { NSLog(@"%zd --%@",i,[NSThread currentThread]); } }); dispatch_group_async(group, queue, ^{ for (int i = 0; i<5; i++) { NSLog(@"%zd --%@",i,[NSThread currentThread]); } }); dispatch_group_wait(group, 10); dispatch_group_notify(group, queue, ^{ for (int i = 0; i<5; i++) { NSLog(@"dispatch_group_notify %@ 组里的所有任务都执行完成后,执行notify",[NSThread currentThread]); } }); NSLog(@"group end..."); 2017-09-02 14:42:43.269 GCD测试[11392:150458] 0 --<NSThread: 0x60800026a440>{number = 4, name = (null)} 2017-09-02 14:42:43.269 GCD测试[11392:150459] 0 --<NSThread: 0x60800026a2c0>{number = 3, name = (null)} 2017-09-02 14:42:43.269 GCD测试[11392:150424] group end... 2017-09-02 14:42:43.269 GCD测试[11392:150458] 1 --<NSThread: 0x60800026a440>{number = 4, name = (null)} 2017-09-02 14:42:43.269 GCD测试[11392:150459] 1 --<NSThread: 0x60800026a2c0>{number = 3, name = (null)} 2017-09-02 14:42:43.270 GCD测试[11392:150458] 2 --<NSThread: 0x60800026a440>{number = 4, name = (null)} 2017-09-02 14:42:43.270 GCD测试[11392:150459] 2 --<NSThread: 0x60800026a2c0>{number = 3, name = (null)} 2017-09-02 14:42:43.270 GCD测试[11392:150458] 3 --<NSThread: 0x60800026a440>{number = 4, name = (null)} 2017-09-02 14:42:43.270 GCD测试[11392:150459] 3 --<NSThread: 0x60800026a2c0>{number = 3, name = (null)} 2017-09-02 14:42:43.270 GCD测试[11392:150458] 4 --<NSThread: 0x60800026a440>{number = 4, name = (null)} 2017-09-02 14:42:43.271 GCD测试[11392:150459] 4 --<NSThread: 0x60800026a2c0>{number = 3, name = (null)} 2017-09-02 14:42:43.271 GCD测试[11392:150459] dispatch_group_notify <NSThread: 0x60800026a2c0>{number = 3, name = (null)} 组里的所有任务都执行完成后,执行notify 2017-09-02 14:42:43.271 GCD测试[11392:150459] dispatch_group_notify <NSThread: 0x60800026a2c0>{number = 3, name = (null)} 组里的所有任务都执行完成后,执行notify 2017-09-02 14:42:43.272 GCD测试[11392:150459] dispatch_group_notify <NSThread: 0x60800026a2c0>{number = 3, name = (null)} 组里的所有任务都执行完成后,执行notify 2017-09-02 14:42:43.272 GCD测试[11392:150459] dispatch_group_notify <NSThread: 0x60800026a2c0>{number = 3, name = (null)} 组里的所有任务都执行完成后,执行notify 2017-09-02 14:42:43.272 GCD测试[11392:150459] dispatch_group_notify <NSThread: 0x60800026a2c0>{number = 3, name = (null)} 组里的所有任务都执行完成后,执行notify