GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
队列 : 用来存放任务(串行队列、并行队列)
并发 : 多个任务同时执行
串行 : 一个任务执行完毕后,再执行下一个任务
全局并发队列(多条)
手动创建串行队列(1条)
主队列(0条)
同步(sync)
需要0条
没有开启新线程
串行执行任务
没有开启新线程
串行执行任务
没有开启新线程
串行执行任务
异步(async)
需要多条
有开启新线程
并发执行任务
有开启新线程
串行执行任务
没有开启新线程
串行执行任务
我的记忆方法(仅仅是记忆方法): 把队列看成具有新开线程的能力,但是他们能力有限不能无限开,把任务看成需要线程的数量。根据需求和队列能力得到最后的先开线程的数量(数量如表格)。
对应方法 :
同步方式执行任务 : dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
异步方式执行任务 : dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
获取全局并发队列 : dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
创建串行队列 : dispatch_queue_create(const char *label, dispatch_queue_attr_t attr); // 队列名称、队列属性(一般用NULL即可)
获得主队列 : dispatch_get_main_queue();
延时函数 :
(1) [self performSelector:(SEL) withObject:(id) afterDelay:(NSTimeInterval)];//对象方法,只能在当前的线程还要写一个方法
(2) dispatch_after(dispatch_time(dispatch_time_t when, int64_t delta), dispatch_queue_t queue, ^(void)block)
参数说明 :
//when可以设置为0也可以用DISPATCH_TIME_NOW,表示从现在开始
//delta 一般传入 (int64_t)(X * NSEC_PER_SEC) 其中X表示多少秒后
//NSEC_PER_SEC打印出来是1000000000
// dispatch_time_t其实是unsigned long long
// int64_t 其实是 long long
单例模式 :
+(id)ShareManager
{
static MyManager * staticInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
staticInstance = [[self alloc]init];
});
return staticInstance;
}
队列组使用步骤: (多个耗时操作都完成之后执行操作)
1.创建队列组 :dispatch_group_t group = dispatch_group_create();
2.创建组任务添加到组中 :dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, ^(void)block);
3.等队列组里面的任务都执行完毕再执行其他操作 : dispatch_group_notify(dispatch_group_t group, dispatch_queue_t queue, ^(void)block);
注意点和知识点 :
(1 )如果使用的是非ARC,创建队列也要释放,凡是函数名中带有create/copy/new/retain,都需要在不需要使用这个数据的时候进行release。但是CF(core Foudation)的数据类型在ARC环境下还是要release
(2)同步函数不能放在主线程中,在主线程往主队列中添加任务(会卡住)。因为串行队列是执行一个任务完才会执行下一个
(3)GCD已经提供了全局的并发队列,供整个应用使用,不需要手动创建;串行队列要自己创建。
(4) 任务的取出队列FIFO原则 : 先进先出,后进后出