博客> GCD的基本用法
GCD的基本用法
2019-12-10 04:06 评论:0 阅读:1259 蓝波大人
GCD

1.Dispatch Queue 是执行处理的等待队列,通过disoatch_async等函数,按照先进先出顺序追加到Queue中处理 执行处理时,存在两种Dispatch Queue: Serial(main) Dispatch Queue 串行:等待现在正在执行的任务处理结束 Concurrent(Global) Dispatch Queue并行(并发):不等待现在正在执行的任务处理结束

所有跟UI界面有关的操作都必须放在主线程里面执行,所以要追加到Main Dispatch Queue

2,GCD的使用 1.创建队列 //创建串行队列 queue = dispatch_queue_create("serial1", NULL); queue = dispatch_queue_create("serial1",DISPATCH_QUEUE_SERIAL);

//创建并行队列 queue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT); 获取所有程序都能访问的全局的queue,第一个参数为队列的优先级,第二个参数为系统保留的参数,属于全局的concurrent Queue queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

2.添加任务 提交一个异步任务 的block到队列里面并且直接返回,不用等待dispatch_async 在异步操作里面提交同步执行的任务。相当于在后台线程里面提交同步执行的任务,当前任务就是在后台线程里面执行

提交一个同步任务 的block到队列里面并且等待dispatch_sync(容易引起死锁) 在主线程里面提交同步执行的任务,当前任务就是在主线程里面执行的

死锁的两种情况: / 死锁1 / //获取主队列 dispatch_queue_t queue = dispatch_get_main_queue(); //2个动作,一个是添加,一个是具体任务。在主线程里面添加任务,因为是同步,所以要等添加的任务执行完成才能继续往下走。 //但是新添加的任务排在队列的末尾,要执行完成必须等添加的动作完成,就变成了你在等我,我在等你这样的死循环,由此又回到了第一步,程序卡死。 dispatch_sync(queue, ^{ NSLog(@"sycn1"); });

NSLog(@"end lock1”);

/ 死锁2 / dispatch_queue_t queue = dispatch_get_main_queue();

//虽然是异步添加,但是在异步里面又有同步添加,且在主线程里面实现
dispatch_async(queue, ^{

    dispatch_sync(queue, ^{
        NSLog(@"sycn2");
    });

    NSLog(@"end lock2");
});

3.延迟任务 dispatch_after这个与sleep延迟的区别在于,前则只是等待2s不管任务有没有执行完都添加,,sleepForTimeInterval是先添加了,在延迟2s后在执行

//DISPATCH_TIME_NOW当前的时间,(ino64_t)(2 NSEC_PER_SEC)延迟2s dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,(ino64_t)(2 NSEC_PER_SEC));

//获取当前的时间 CFAbsoluteTime beginTime = CFAbsoluteTimeGetCurrent();

dispatch_after(time, dispatch_get_main_queue(), ^{ NSLog(@"delay time:%lf", CFAbsoluteTimeGetCurrent() - beginTime);//得到延迟的时间 });

面试题:diapatch_after与NSDelayedPerforming的区别

4.单例

dispatch_once保证里面的代码块在应用程序中只执行一次,无论是不是多线程 +(instancetype)shareInstance { // 1.声明一个静态变量 static Person *instance = nil; static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

// instance = [[self alloc]init]; //将两个语句结合在一起 instance = [[super allocWithZone:nil]init]; }); return instance; }

重写两个父类方法 +(instancetype)allocWithZone:(struct_NSZone *)zone { return [self shareInstance]; }

-(id)copy { return self; }

5.挂起任务 挂起(暂停队列里面尚未开始执行的任务,对已经开始的任务没有作用) 当队列生成后就会有任务添加到里面去执行,所以挂起任务对它没有用处,就算延迟任务的执行,也只是延迟了此任务的执行但是它早已经添加到队列里面了 //挂起队列 dispatch_suspend(suspensQueue); //恢复队列 dispatch_resume(suspensQueue);

6.设置优先级(dispatch_set_target_queue)

在没有设置优先级前线程的任务执行是随机的,设置优先级后,执行的顺序按照设置优先级的顺序执行

//设置优先级,改变queue1的优先级与targetQueue相同,其实就是将任务添加到又添加到了一个大的串行的队列里面执行了,执行的顺序就变成添加到队列里面的顺序执行 dispatch_set_target_queue(queue1, targetQueue);

收藏
1
sina weixin mail 回到顶部