08-GCD常用方法
GCD常用方法
一.延迟执行方法
NSTimer
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(demo) userInfo:nil repeats:NO];
performSelector:withObject:afterDelay:
[self performSelector:@selector(demo) withObject:nil afterDelay:3.0];
GCD
// 该方法中, 会根据传入的队列来决定回掉block在哪个线程中执行
// 如果传入的是主队列, 那么block会在主线程调用
// 如果传入的是全局队列, 那么block会在子线程中调用
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
NSLog(@"3秒之后执行 %@", [NSThread currentThread]);
});
二.一次性代码方法
- 整个程序运行过程中只会执行一次
注意
千万不呢过把一次性代码当做懒加载来使用
- (void)touchesBegin:
{
//要选dispatch_once snippet - GCD:Dispatch Once
//默认生成以下代码
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
NSLog(@"我被执行过");
});
}
三.快速遍历
- dispatch_apply(size_ t, dispatch_ queue_ t, ^(size_ t) block);
- 参数解释
- 第一个参数(size_ t ):需要遍历几次
- 第二个参数(dispatch_ queue_ t):决定第三个参数的block在哪个线程中执行
- 第三个参数(^(size_t)block):回掉
dispatch_apply(10,dispatch_get_globa_queue(0,0),^(size_t index)){
NSLog(@"index = %zd=======%@",size_t_index,[NSTThread currentThread]);
});
快速遍历应用--多个文件的剪切(迅雷下载)
- 1.定义变量记录原始文件夹和目标文件夹的路径
- 2.取出原始文件夹中所有文件
- 3.开始卡拷贝文件
- 3.1生成原始文件的绝对路径
- 3.2生成目标文件的绝对路径
- 3.3利用NSFileManager拷贝文件
//1.定义变量记录原始文件夹和目标文件夹的路径
NSString *scourePath = @"目标文件夹的绝对路径";
NSString *destPath = @"目标文件夹的绝对路径";
//2.取出原始文件夹中所有文件
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *files = [manager subpathsAtPath:sourcePath];//获取的是 文件夹的名称.扩展名
- 方法一: 使用for循环一个一个移动文件
//3.开始剪切文件
for(NSString *fileName in files)
{
//3.1生成原始文件的绝对路径
NSString *scourceFilePath = [scourcePath stringByAppendingPathComponent:fileName];
//3.2生成目标文件的绝对路径
NSString *destFilePath = [destPath stringByAppendingPathComponent:fileName];
//3.3利用NSFileManager拷贝文件
[manager moveItemAtPath:destFilePath toPath:destPath error:nil];//有BOOL返回值
}
- 方法二: 使用GCD的快速遍历 同时剪切文件
//3.开始剪切文件
dispatch_apply(files.count,dispatch_queue_global_queue(0,0),^(size_t index){
NSString *fileName = files[index];
//3.1生成原始文件的绝对路径
NSString *scourceFilePath = [scourcePath stringByAppendingPathComponent:fileName];
//3.2生成目标文件的绝对路径
NSString *destFilePath = [destPath stringByAppendingPathComponent:fileName];
//3.3利用NSFileManager拷贝文件
[manager moveItemAtPath:destFilePath toPath:destPath error:nil];//有BOOL返回值
});
四.小案例(栅栏和多线程的应用)
栅栏
- 栅栏的功能
- 拦截前面的任务,只有先添加到队列中的任务执行完毕,才会执行栅栏中添加的任务
- 只有执行完栅栏,才会执行后面的任务
- dispatch_barrier_async()
注意
- 如果想要使用栅栏,那么就不能使用全局并发队列
- 如果想使用栅栏,所有的任务必须添加到同一队列中
--
dispatch_group _async()组
- 应用场景: 任务之间有依赖关系的时候用
- 栅栏比组多了一个对后面任务执行顺序的限制功能
- 只要将任务和队列放入group中,group中的任务之行为完毕,group就会发出一个通知
- dispatch_group_notify(group,queue,^{});
注意
应放入同一个组中
--
案例
- 需求: 下载两张图片,合成一张之后展示在UI界面上
- 分析
- 开启一个线程,下载第一张图片
- 开启新线程,下载第二张图片
- 开启新线程,合成图片
- 开启图形上下文
- 将第一张图片画上去
- 将第二张图片画上去
- 从上下文中获取绘制好的图片
- 关闭上下文
- 回到主线程更新UI
//1.开启一个线程,下载第一张图片
//2.开启新线程,下载第二张图片
//3.开启新线程,合成图片
//3.1开启图形上下文
//3.2将第一张图片画上去
//3.3将第二张图片画上去
//3.4从上下文中获取绘制好的图片
//3.5关闭上下文
//4.回到主线程更新UI