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

 

 

posted on 2017-09-01 18:02  HJiang  阅读(260)  评论(0编辑  收藏  举报