什么是GCD Grand Central Dispatch
大中央调度
主要是为多核并行运算提出的解决方案
会自动管理线程的生命周期(创建线程,调度任务 销毁线程)
GCD会自动将队列中的操作对象取出 放到线程中执行
将任务添加到队列 指定任务执行的方法
任务就是 用block封装的那部分
基本概念
NSOperation 操作对象
也可以叫任务
操作对象可以将需要执行的代码和相关的数据 集成并封装
操作对象一般不是直接执行 而是在等待队列中被按顺序调用 但是操作对象也可以直接调用start方法来执行任务
线程数量是由硬件或当前系统的整体符合等条件决定
NSOperationQueue 操作队列
同步和异步(同步不会开线程 异步会开线程)
同步:一个任务没有结束不会执行下一个任务 不会增加新线程 不会倒线程池里面获取子线程
异步:不用等待前面的任务执行完毕 会执行下一个任务 具备开启线程的能力 只要有任务就回去线程池获取子线程(主线程除外)
在主队列,主线程里面不会因为异步而创建新的子线程 只会在主队列里同步执行 无论用dispatch_async还是dispatch_sync在主线程 主队列中都是同步执行
串行,并发(串行是顺序执行 并发不是)
串行和并发只是决定如何去拿任务
Serial DisPatch Queue 串行调度队列 从队列中一个一个的拿出任务
Concurrent Dispatch Queue 并发调度队列 可以同时调度多个任务出来
还有一种是主队列 Main Dispatch Queue。是串型队列
dispatch_queue_t
dispatch_queue_create() 创建串行 并发队列
dispatch_queue_t q = dispatch_queue_create("queueName",DISPATCH_SERIAL);//创建串行队列 DISPATCH_SERIAL可以用NULL代替
dispatch_queue_t q = dispatch_queue_create("queueName",DISPATCH_QUEUE_CONCURRENT);//创建并发队列
dispatch_get_global_queue() 获取系统提供的全局队列
系统会给每一个应用程序提供三个 concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不同
DISPATCH_QUEUE_PRIORITY_HIGH 高优先级
DISPATCH_QUEUE_PRIORITY_LOW 低优先级
DISPATCH_QUEUE_PRIORITY_BACKGROUND 后台运行队列
DISPATCH_QUEUE_PRIORITY_DEFAULT 默认优先级
因为是全局的,我们不需要去创建。我们只需要通过使用函数dispath_get_global_queue去得到队列
//方法定义
dispatch_get_global_queue(intptr_t identifier, uintptr_t flags);
//方法使用
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//第二个参数基本就传0
解决耗时问题
比如说为了避免在读取网络数据或者IO读写的时候界面因为处理耗时的操作而卡死
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 耗时的操作
dispatch_async(dispatch_get_main_queue(), ^{
// 更新界面
});
});
dispatch_get_main_queue() 返回主线程队列
dispatch_queue_t q = dispatch_get_main_queue();
dispatch_sync()和dispatch_async() 添加任务到队列 同步,异步执行
dispatch_sync() 同步执行
dispatch_async() 异步执行
//第一个参数是任务队列 第二个参数是方法块
dispatch_sync(dispatch_queue_t queue, DISPATCH_NOESCAPE dispatch_block_t block);
//方法使用
void (^taks)() = ^{
NSLog(@"%@",[NSThread currentThread]);
};
dispatch_sync(q, taks);
//简化
dispatch_sync(q,^{ //同步执行
NSLog(@"%@",[NSThread currentThread]);
};
dispatch_async(q,^{ //异步执行
NSLog(@"%@",[NSThread currentThread]);
};
例子
dispatch_queue_t serialQ= dispatch_queue_create("queueName",DISPATCH_SERIAL);//创建串行队列 DISPATCH_SERIAL可以用NULL代替
dispatch_queue_t concurrentQ= dispatch_queue_create("queueName",DISPATCH_QUEUE_CONCURRENT);//创建并发队列
dispatch_sync(serialQ,^{ //串行同步执行
NSLog(@"%@",[NSThread currentThread]);
};
dispatch_async(serialQ,^{ //串行异步执行 就可能导致任务执行在不同的线程上
NSLog(@"%@",[NSThread currentThread]);
};
dispatch_sync(concurrentQ,^{ //并行同步执行
NSLog(@"%@",[NSThread currentThread]);
};
dispatch_async(concurrentQ,^{ //并行异步执行
NSLog(@"%@",[NSThread currentThread]);
};
串行队列、并行队列的作用是确定任务可同时执行的数量。
同步方法、异步方法的作用是执行该任务是否开启新的线程。
所以串行队列里的任务也可能会在不同的线程内执行,只有一个任务在执行