1.什么是GCD
Grand Central Dispatch(GCD)是异步执行任务的技术之一。提供了对底层线程管理的实现。开发者只需要定义想执行的任务并追加到适当的Dispatch Queue中,GCD就会生成必要的线程并计划执行任务。dispatch_async(queue,^
{
/*
*执行任务
*/
});
2.Dispatch Queue
Dispatch Queue是执行处理的FIFO(先进先出)等待队列,按照执行处理的方式分为Serial Dispatch Queue和Concurrent Dispatch Queue。 Serial Dispatch Queue 只使用一个线程来执行处理,要等待现在执行中的处理结束才会执行下一个处理, Concurrent Dispatch Queue 采用多个线程来执行处理,不等待现在执行中的处理结束,具体的线程数由iOS和OSX的内核-- XNU 决定,XUN动态的根据要执行的任务数来增加和减少线程。创建Serial Dispatch Queue
dispatch_queue_t serialDispatchQueue = dispatch_queue_create("SerialDispatchQueueName",NULL);
dispatch_async(serialDispatchQueue,^
{
});
dispatch_release(serialDispatchQueue);
创建Concurrent Dispatch Queue
dispatch_queue_t concurrentDispatchQueue = dispatch_queue_create("ConcurrentDispatchQueueName",DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentDispatchQueue,^
{
});
dispatch_release(concurrentDispatchQueue);
2.1 Main Dispatch Queue
Main Dispatch Queue是在主线程Runloop中执行处理的Serial Dispatch Queue。dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();
2.2 Global Dispatch Queue
Global Dispatch Queue是Concurrent Dispatch Queue,Global Dispatch Queue有四个执行优先级,分别是高优先级(High Priority)、默认优先级(Default Priority)、低优先级(Low Priority)和后台优先级(Background Priority)。获取方法如下://高优先级 Global Dispatch Queue
dispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);
//默认优先级 Global Dispatch Queue
dispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
//低优先级 Global Dispatch Queue
dispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0);
//后台优先级 Global Dispatch Queue
dispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0);
2.3 常用的Main和Global模型
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^()
{
//并行处理任务
dispatch_async(dispatch_get_main_queue(),^()
{
//主线程中执行处理
});
});
3.GCD的API
3.1 dispatch_after
dispatch_after并不是在指定的时候后执行处理,而只是在指定的时间后追加处理到指定的Dispatch Queue,具体执行时间还要看当前线程的执行情况,3秒后追加指定的Block到Main Dispatch Queue中执行:dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,3ull*NSEC_PER_SEC);
dispatch_after(time,dispatch_get_main_queue,^()
{
//3秒后的处理
});
3.2 dispatch_once
dispatch_once函数保证在应用程序的生命周期内只执行一次指定处理的API,单例的实现中常用到。使用方式如下:static dispatch_once_t token;
dispatch_once(&token,^()
{
});
3.3 Dispatch Group
Dispatch Group主要是用于在追加到Dispatch Queue中的多个处理全部处理结束后想执行结束处理的情况,最后想要执行的结束处理的追加可以采用同步(dispatch_group_wait())或者异步(dispatch_group_notify())两种方式。dispatch_group_wait()会阻塞该函数调用的线程,直到添加到Group中的处理全部执行完毕才执行结束处理,而dispatch_group_notify()不会阻塞,会立刻返回,当追加到Group中的所有处理都执行完成的时候,会将指定的Block追加到指定的Dispatch Queue中。具体Dispatch Group使用方式如下:异步:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group,queue,^{ NSLog(@"TestBlock1"); });
dispatch_group_async(group,queue,^{ NSLog(@"TestBlock2"); });
dispatch_group_notify(group,dispatch_get_main_queue(),^{ NSLog(@"Done"); });
同步:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group,queue,^{ NSLog(@"TestBlock1"); });
dispatch_group_async(group,queue,^{ NSLog(@"TestBlock2"); });
dispatch_group_wait(group,DISPATCH_TIME_FOREVER);
NSLog(@"Done");
3.4 dispatch_sync
dispatch_async是异步的追加Block到指定的Dispatch Queue中,不会阻塞当前函数的线程。而dispatch_sync会阻塞当前函数调用的线程直到追加的Block执行完成。dispatch_sync的功能类似于dispatch_group_wait,阻塞当前线程直到另外一个线程完成了追加的Block的执行,如果当前线程和要处理Block的线程相同,就会造成线程死锁。死锁代码如下:dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue,^
{
dispatch_sync(queue,^{ NSLog(@"线程死锁"); });
});
3.5 dispatch_apply
dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联API,该函数按指定次数将指定的Block追加到指定的Dispatch Queue中,并等待全部处理执行结束后返回。dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY, 0 );
dispatch_apply(10,queue,^(size_t index)
{
NSLog(@"%zu",index);
});
NSLog(@"Done");
3.6 dispatch_barrier_async
dispatch_barrier_async主要是和Concurrent Dispatch Queue结合起来使用,起到线程中栅栏的作用,等待该函数调用之前所有添加到Dispatch Queue中的处理执行完成之后才执行该函数要添加的处理,在该函数添加的处理执行完成后,后续添加到Dispatch Queue的处理才能执行。dispatch_queue_t queue = dispatch_queue_create(@"ConcurrentDispatchQueue",DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue,Block1ForReading);
dispatch_async(queue,Block2ForReading);
dispatch_async(queue,Block3ForReading);
dispatc_barrier_async(queue,BlockForWriting);
dispatch_async(queue,Block4ForReading);
dispatch_async(queue,Block5ForReading);
dispatch_async(queue,Block6ForReading);
dispatch_release(queue);
3.7 dispatch_set_target_queue
dispatch_set_target_queue可以用来改变目标Dispatch Queue的优先级为目标Dispatch Queue的优先级。dispatch_queue_t myQueue = dispatch_queue_create(@"myQueue",0);
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);
dispatch_set_target_queue(myQueue,globalQueue);
3.8 dispatch_suspend / dispatch_resume
dispatch_suspend函数挂起指定的Dispatch Queuedispatch_suspend(queue);
dispatch_resume会恢复指定的Dispatch Queue
dispatch_resume(queue);
3.9 Dispatch Semaphore
GCD提供了线程的信号量处理函数:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
dispatch_semaphore_signal(semaphore);