一、GCD使用
使用步骤:
1、定制任务
2、将任务添加到队列中
GCD执行任务的两种方式:
1、同步:只能在当前线程中执行任务不具备开线程的功能
dispatch_sync(dispatch_queue_t queue,dispatch_block_t
block);
2、异步:可以在新的线程中执行任务,具备开线程的能力
dispatch_async(dispatch_queue_t queue,dispatch_block_t
block);
参数分析:
1、queue:队列对象
GCD的队列有两种:
1)并发队列:多个任务同时进行(自动开启多个线程执行任务)PS:只能在异步方式汇中才能有效。
2)串行队列:让任务一个一个地执行。
通常申明一个对了对象的属性,使用strong
@property (nonatomic, strong)dispatch_queue_t queue;
在写一个framwork时候为了适应ios6之前,需要根据OS_OBJECT_USE_OBJC判断一下使用strong或是assign:
#if OS_OBJECT_USE_OBJC
@property(nonatomic, strong)dispatch_queue_t queue;
#else
@property (nonatomic,assign) dispatch_queue_t queue;
#endif
2、block:执行的任务
1、并发队列
并发队列:已由GCD创建好,只需调用函数即可得到全局的并发队列。可在整个应用使用。
使用以下这个函数获得
dispatch_get_global_queue(long identifier, //队列优先级
unsigned long flags//预留参数,暂时无用、为0
);
PS:全局并发队列的优先级:
#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默认(中)
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台执行
二、并发与串行
2、串行队列
与并发队列不同、串行队列的获得有两种方法:
1) 由dispatch_queue_create函数创建:
获取方法:
dispatch_queue_t
dispatch_queue_create(const char *label, // 队列名称,注意此处是C语言字符串
dispatch_queue_attr_t attr);// 队列属性,一般用NULL即可
dispatch_queue_t queue = dispatch_queue_create("cn.itcast.queue", NULL); //创建
dispatch_release(queue); // 非ARC需要释放手动创建的队列
2)使用主队列(跟主线程相关联的队列)
主队列是GCD自带的一种特殊的串行队列放在主队列中的任务,都会放到主线程中执行。
获取方法:
使用dispatch_get_main_queue()获得主队列 dispatch_queue_t queue = dispatch_get_main_queue();
任务执行方式和队列组合情况分析:
同步任务(包括主线程)下不会开启新线程,不管是并发还是串行最终都是串行执行。
异步任务(除主线程)下会开启新线程,正常执行并发和串行任务,
主线程下不管是同步还是异步执行都不开启新线程,只是串行执行。
PS:在串行队列(包括主队列)任务下使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列(插入任务与当前任务互相等待出行死锁)。
三、GCD的进程间通信
从子线程回到主线程:
// 发出一个异步任务
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行耗时的异步操作
//…
// 执行异步任务完成,回到主线程
dispatch_async(dispatch_get_main_queue(),^{
// 回到主线程,执行UI刷新操作
});
});