zoukankan      html  css  js  c++  java
  • 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
    
  • 相关阅读:
    mysql 从库执行insert失败导致同步停止
    MySQL 占用cpu 100%
    MySQl 主从配置实战
    tomcat 线程数与 mysql 连接数综合调优
    mysql 数据迁移
    Windows系统上设置 Git Bash 的 Font 及 Locale
    java -jar 使用要点
    ConcurrentHashMap 从Java7 到 Java8的改变
    sql索引组织
    注册、启动、停止windows服务
  • 原文地址:https://www.cnblogs.com/KrystalNa/p/4780327.html
Copyright © 2011-2022 走看看