GCD常见的几种用法 -- 延迟\一次性代码\多线程同时遍历\栈栏
1.实现延迟
// 参数:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"+++++++%@", [NSThread currentThread]);
});
NSLog(@"=======");
2. 一次性代码
// 会根据是异步还是同步函数,确定在什么线程执行,即便是多条线程同时执行也只会执行一次,内部加了互斥锁
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"------%@", [NSThread currentThread]);
});
3. 快速迭代遍历:会多条线程同时遍历,常用语同时执行某个比较耗时的操作,比如,拷贝文件
/*
第一个参数: 需要遍历几次
第二个参数: 决定第三个参数的block在哪个线程中执行
第三个参数: 回调block
*/
dispatch_apply(10.0,dispatch_get_global_queue(0, 0), ^(size_t index) {
NSLog(@"%zd" ,index);
});
NSString *str = @"xiaobing";
NSString *str1 = [str stringByAppendingString:@"heh"];
NSLog(@"%@",str1);
// 文件拷贝
// 1.获取需要拷贝的文件夹的路径
NSString *sourcePath = @"/Users/xiaobing/Desktop/001";
// 2.获取目标文件夹路径
NSString *destPath = @"/Users/xiaobing/Desktop/002";
// 3.获取拷贝文件夹里面每个文件文件名
// NSArray *pathArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:sourcePath error:nil];
// NSArray *path = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:sourcePath error:nil];
NSArray *files = [[NSFileManager defaultManager] subpathsAtPath:sourcePath];
NSLog(@"%@", files);
// 4.遍历文件夹里面的文件一个个拷贝
dispatch_apply(files.count,dispatch_get_global_queue(0, 0), ^(size_t index) {
// NSString *filePath = pathArray[index];
// 1.获得file的名字
NSString *fileName = files[index];
// 1.原始文件的绝对路径
// 注意:不能用这个方法:
// 这个方法不会自动生成/斜线
// NSString *sourceFilePath = [sourcePath stringByAppendingString:fileName];
// /Users/xiaobing/Desktop/001/Snip20150818_63.png
// 应用这个方法:会自动生成/加文件的名字
NSString *sourceFilePath = [sourcePath stringByAppendingPathComponent:fileName];
// 2.目标文件的绝对路径
NSString *destFilePath = [destPath stringByAppendingString:fileName];
// 3.拷贝文件
[[NSFileManager defaultManager] moveItemAtPath:sourceFilePath toPath:destFilePath error:nil];
// });
4.栈栏
// 自定义一个并发队列
dispatch_queue_t queue = dispatch_queue_create("xiaobing", DISPATCH_QUEUE_CONCURRENT);
// 栅栏
// 功能:
// 1.拦截前面的任务, 只有先添加到队列中的任务=执行完毕, 才会执行栅栏添加的任务
// 2.如果栅栏后面还有其它的任务, 那么必须等栅栏执行完毕才会执行同一个队列后面的其它任务
// 注意点:
// 1.如果想要使用栅栏, 那么就不能使用全局的并发队列
// 2.如果想使用栅栏, 那么所有的任务都必须添加到同一个队列中
// dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
// NSLog(@"%@", [NSThread currentThread]);
for (int i = 0; i <= 100; i++) {
NSLog(@"%i", i);
}
});
dispatch_async(queue, ^{
// NSLog(@"%@", [NSThread currentThread]);
for (int i = 0; i <= 100; i++) {
NSLog(@"%i", i);
}
});
// 栈栏函数
dispatch_barrier_async(queue, ^{
NSLog(@"%@", [NSThread currentThread]);
});
// 这个任务会等栈栏里面的任务执行完毕之后才会执行
dispatch_async(queue, ^{
NSLog(@"----------");
});
NSLog(@"+++++++");