GCD常用函数和文件剪切

来源:互联网 发布:一年程序员觉得很累 编辑:程序博客网 时间:2024/05/17 02:58

一 延迟操作

1 延迟操作:就是将某些代码间隔一段时间在执行.时间完全由程序猿自己控制.

2 非多线程的两种延迟操作方法:

2.1 方法调用的代码:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{    //调用需要执行的方法    [self 方法名];}
2.2 第一种:
-(void)delay{    //打印出程序开始执行的时间,用于和延迟代码执行的时间做对比    NSLog(@"---start----");    //第一个参数:延迟操作需要执行的任务    //第二个参数:延迟操作中任务是否需要参数    //第三个参数:延迟执行时间    [self performSelector:@selector(task:) withObject:nil afterDelay:2.0];
2.3 第二种:定时器
-(void)delay{    //打印出程序开始执行的时间,用于和延迟代码执行的时间做对比    NSLog(@"---start----");    //第一个参数:定时执行时间    //第二个参数:目标对象    //第三个参数:定时结束需要执行的任务    //第四个参数:一般穿nil    //第五个参数:是否重复    [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(task) userInfo:nil repeats:NO];
2.4 第三种: 线程定时
 /*     第一个参数:DISPATCH_TIME_NOW 从什么时候开始计时     第二个参数:延迟的时间 2.0表示2秒 GCD的时间是以纳秒为单位     第三个参数:队列        dispatch_get_main_queue()  主线程        如果是其他队列(并发|串行),那么block在子线程中调用     */    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{        //打印出执行的线程        NSLog(@"--GCD----%@",[NSThread currentThread]);    });

二 栅栏函数

1 字面概念: 所谓栅栏函数,字面意思就是在代码的某个地方建立起一座栅栏,不让栅栏后面的代码执行,直到把栅栏拆了,才可以执行后面的代码

2 实际的概念是

01 开始执行之前确保前面的任务都已经执行完毕
02 只有当栅栏函数执行完毕之后,后面的任务才能继续执行
-(void)barrier{    //1.创建队列concurrent:并发    dispatch_queue_t queue = dispatch_queue_create("com.download", DISPATCH_QUEUE_CONCURRENT);    //封装任务    dispatch_async(queue, ^{        for (NSInteger i = 0; i<5; i++) {            NSLog(@"download1---%zd--%@",i,[NSThread currentThread]);        }    });    dispatch_async(queue, ^{        for (NSInteger i = 0; i<5; i++) {            NSLog(@"download2---%zd--%@",i,[NSThread currentThread]);        }    });    //栅栏函数    //1.在子线程中执行    //2.开始执行之前确保前面的任务1和任务2都已经执行完毕    //3.只有当我执行完毕之后才能继续执行后面的任务    dispatch_barrier_async(queue, ^{        NSLog(@"+++++++++++++%@",[NSThread currentThread]);    });    dispatch_async(queue, ^{        for (NSInteger i = 0; i<5; i++) {            NSLog(@"download3---%zd--%@",i,[NSThread currentThread]);        }    });    dispatch_async(queue, ^{        for (NSInteger i = 0; i<5; i++) {            NSLog(@"download4---%zd--%@",i,[NSThread currentThread]);        }    });
03 栅栏函数补充:barrier在使用的时候不能使用全局并发队列,如果使用了将失去拦截功能
原因:详见苹果官方文档给出的说明

苹果官方文档

如果是使用了全局并发队列,代码执行的结果是前面的任务并没有执行完毕就开始执行栅栏函数

这里写图片描述

三 一次性代码

1 概念:

01 整个应用程序只会执行一次
执行一次的原因:static dispatch_once_t 静态变量
02 本身是线性安全的—->相当于加锁的功能
-(void)once{    //通过打印是否程序运行时候进入该方法,第一次会全部执行,但是继续点击的时候只会打印once,并不会打印一次性代码中的任务    NSLog(@"------%s",__func__);     static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        NSLog(@"--once---%@",[NSThread currentThread]);    });}

四 快速迭代

1 概念:循环的意思

2 两种方法:for循环和快速迭代

3 for循环

//串行执行    for (NSInteger i = 0; i<10; i++) {        NSLog(@"%zd---%@",i,[NSThread currentThread]);    }

4 快速迭代

01 并发队列的快速迭代
 /*     第一个参数:迭代的次数     第二个参数:队列     注意:主线程也会参与迭代的过程,里面的任务是并发执行的     */    //如果是串行队列,和for循环没区别    dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index) {        NSLog(@"%zd---%@",index,[NSThread currentThread]);    });
02 串行队列快速迭代(和传统的for循环没有区别,都是在主线程中进行)
  dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_SERIAL);    //主线程和子线程都会参与    dispatch_apply(10, queue, ^(size_t index) {        NSLog(@"%zd---%@",index,[NSThread currentThread]);    });
03 传主队列到快速迭代中会出现死锁
死锁原理图:

死锁原理图

死锁原理:由于快速迭代执行参与的是主线程和子线程,当使用主队列的时候,代码执行到任务,将任务加入到主队列.然后就开始执行主队列的任务,由于所有的任务都是在主队列中执行,会出现等待任务的执行,所有会出现死锁.

五 文件剪切

1 需求:将from中的文件,通过代码剪切到另外一个文件to中

2 思路:运用快速迭代实现剪切文件内容

代码详解
  //获取文件的路径    NSString *sourePath = @"/Users/xiaofeng/Desktop/from";    //确定要剪切的文件路径    NSString *targetPath = @"/Users/xiaofeng/Desktop/to";    //得到文件夹中的所有文件    NSArray *subPaths = [[NSFileManager defaultManager] subpathsAtPath:sourePath];    NSLog(@"%@",subPaths);    //执行迭代.把所有的文件都剪切到制定的地方    //第一个参数:迭代次数    //第二个参数:迭代的队列    dispatch_apply(subPaths.count, dispatch_get_global_queue(0, 0), ^(size_t index ) {       //根据角标,拿到文件夹中所有的文件名字--->是字符串        NSString *fileName = subPaths[index];        NSLog(@"%@",fileName);        //拼接文件的全路径        NSString *soureFullpath = [sourePath stringByAppendingPathComponent:fileName];        //剪切的目的地        NSString *targetFullpath = [targetPath stringByAppendingPathComponent:fileName];        //执行剪切操作        [[NSFileManager defaultManager] moveItemAtPath:soureFullpath toPath:targetFullpath error:nil];        NSLog(@"%@----%@----%@",soureFullpath,targetFullpath,[NSThread currentThread]);    });
1 0
原创粉丝点击