美文网首页iOS 多线程iOSiOS 的那些事儿
GCD(一次性代码、栅栏函数、延迟执行、定时器)

GCD(一次性代码、栅栏函数、延迟执行、定时器)

作者: lyonLiu | 来源:发表于2016-09-22 11:53 被阅读514次

    一次性代码多用于单例


    作用:程序运行过程中直到销毁只会执行一次`

    - (void)once{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            NSLog(@"once");
        });
    }
    

    延迟执行


    - (void)delay
    {   
        // 1.延迟执行的第一种方法
        [self performSelector:@selector(task) withObject:nil afterDelay:2.0];
    
        // 2.延迟执行的第二种方法
        [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(task) userInfo:nil repeats:YES];
    
        // 3.延迟执行的第三种方法
        /**
         第一个参数:DISPATCH_TIME_NOW 从现在开始计算事件
         第二个参数:延迟的时间 GCD时间单位:那秒
         第叁个参数:队列
         */
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"GCD ----  %@",[NSThread currentThread]);
        });
    }
    - (void)task
    {
        NSLog(@"task ----  %@",[NSThread currentThread]);
    }
    

    栅栏函数


    作用:只有当栅栏函数执行完毕后才能执行后面的函数
    需求:使用栅栏函数规定线程执行顺序

    注意点:栅栏函数不能使用全局并发队列
    再次强调:栅栏函数不能使用全局并发队列
    再再次强调:栅栏函数不能使用全局并发队列

    使用示例

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_CONCURRENT);
        //1.异步函数
        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]);
            }
        });
        
        dispatch_barrier_async(queue, ^{
            NSLog(@"+++++++++++++++");
        });
        
        dispatch_async(queue, ^{
            for (NSInteger i =0 ; i < 5 ; i++){
                NSLog(@"download3 -- %zd -- %@",i,[NSThread currentThread]);
            }
        });
        dispatch_barrier_async(queue, ^{
            NSLog(@"+++++++++++++++");
        });
        
        dispatch_async(queue, ^{
            for (NSInteger i =0 ; i < 5 ; i++){
                NSLog(@"download4 -- %zd -- %@",i,[NSThread currentThread]);
            }
        });
    }
    

    输出结果:

    GCD里面的定时器,绝对精准,不受Runloop影响


    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        // 1.创建GCD中的定时器
        // 1.1 DISPATCH_SOURCE_TYPE_TIMER Source类型 表示定时器
        // 1.2 描述信息:线程ID
        // 1.3 更详细的描述信息
        // 1.4 队列,决定GCD定时器中的任务在哪个线程中执行
        dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
        // 2.设置定时器(起始时间|间隔时间|精准度)
        // 2.1 定时器对象
        // 2.2 起始时间,DISPATCH_TIME_NOW 从现在开始计时
        // 2.3 间隔时间 , 2.0 GCD中时间为纳秒
        // 2.4 精准度 绝对精准 0
        dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
        // 3.设置定时器执行任务
        dispatch_source_set_event_handler(timer, ^{
            NSLog(@"GCD --- %@",[NSThread currentThread]);
        });
        // 4.启动执行
        dispatch_resume(timer);
        
        self.timer = timer;
        // 启动程序,不执行的原因:是因为2秒后timer被释放
    }
    

    相关文章

      网友评论

        本文标题:GCD(一次性代码、栅栏函数、延迟执行、定时器)

        本文链接:https://www.haomeiwen.com/subject/itbgettx.html