多线程07——CGD栅栏函数、延时、一次性代码
一、说明
1.1 栅栏函数说明
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
在前面的任务执行结束后它才执行,除此之外只有它本身执行完了,它后面的任才能被执行
示例代码
dispatch_barrier_async(queue, ^{
NSLog(@"++++++++++++++++++++++++++++++");
});
1.2 延时执行
dispatch_after(dispatch_time_t when,
dispatch_queue_t queue,
dispatch_block_t block);
可以使用已经内置的代码模板
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<delayInSeconds> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
<code to be executed after a specified delay>
});
使用说明
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//2秒钟后执行的代码。。。。。。
});
1.3 一次性代码
使用 dispatch_once 函数能保证某段代码在程序运行过程中只被执行1次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 只执行1次的代码(这里面默认是线程安全的)
});
二、栅栏函数
2.1 说明
我们创建四个任务。在栅栏函数前面创建两个 ,栅栏函数后面创建两个。我们得到的结果应该是:
- 先执行前面两个任务,执行完了到第2步
- 执行栅栏函数,执行完了到第3步
- 执行后面的两个任务
2.2 代码
/*栅栏函数*/
-(void)barrier{
dispatch_queue_t queue = dispatch_queue_create("com.wiming", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
for (int i=0; i<5; i++) {
NSLog(@"download1--%zd---%@",i,[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i=0; i<5; i++) {
NSLog(@"download2--%zd---%@",i,[NSThread currentThread]);
}
});
dispatch_barrier_async(queue, ^{
NSLog(@"++++++++++++++++++++++++++++++");
});
dispatch_async(queue, ^{
for (int i=0; i<5; i++) {
NSLog(@"download3--%zd---%@",i,[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i=0; i<5; i++) {
NSLog(@"download4--%zd---%@",i,[NSThread currentThread]);
}
});
}
2.3 结果
[72846:415833] download1--0---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download2--0---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download1--1---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download2--1---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download1--2---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download2--2---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download1--3---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download2--3---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download1--4---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download2--4---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415834] ++++++++++++++++++++++++++++++
[72846:415834] download3--0---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download4--0---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download3--1---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download4--1---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download3--2---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download4--2---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download3--3---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download4--3---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download3--4---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download4--4---<NSThread: 0x600000076b00>{number = 4, name = (null)}
2.4 结果分析
通过上面的结果我们可以看到
任务1和任务2(download1和download2),首先执行,它们执行完了 才执行 栅栏函数里面的代码,栅栏函数里面的代码执行完了 ,才开始执行任务3和任务4(download3和download4)
三、延时执行
3.1. 调用NSObject的方法
//第一个参数:方法选择器,就是时间到了以后要执行的方法
//第二个参数:方法的参数
//第三个参数:延时的时长
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;
示例代码
/*延时*/
-(void)delay{
NSLog(@"start------");
//第一种方式
[self performSelector:@selector(task) withObject:nil afterDelay:2.0];
}
-(void)task{
NSLog(@"task-------%@",[NSThread currentThread]);
}
结果
2017-09-03 01:48:42.194 03_UIview83多线程GCD[74790:425940] start------
2017-09-03 01:48:44.196 03_UIview83多线程GCD[74790:425940] task-------<NSThread: 0x608000068dc0>{number = 1, name = main}
我们可以看一下时间,确实是2s
01:48:42
01:48:44
3.2 使用NSTime
使用的方式是
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
示例代码
/*延时*/
-(void)delay{
NSLog(@"start------");
//第二种方式
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(task) userInfo:nil repeats:NO];
}
-(void)task{
NSLog(@"task-------%@",[NSThread currentThread]);
}
结果
2017-09-03 03:13:55.639 03_UIview83多线程GCD[77570:439579] start------
2017-09-03 03:13:57.641 03_UIview83多线程GCD[77570:439579] task-------<NSThread: 0x600000074d00>{number = 1, name = main}
3.3 使用GCD函数
示例代码
/*延时*/
-(void)delay{
NSLog(@"start------");
//GCD
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"GCD-------%@",[NSThread currentThread]);
});
}
结果
2017-09-03 03:15:57.027 03_UIview83多线程GCD[78003:442676] start------
2017-09-03 03:15:59.218 03_UIview83多线程GCD[78003:442676] GCD-------<NSThread: 0x608000066cc0>{number = 1, name = main}
四、一次性代码
示例代码
/*一次性代码*/
-(void)once{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"------one------");
});
}
结果 程序运行以后,无论操作多少次都只会执行一次
2017-09-03 03:19:17.991 03_UIview83多线程GCD[78649:447665] ------one------