多线程之GCD(grand central dispatch)中心调度
为了简化多线程的操作,iOS为我们提供了GCD来实现编程。
使用GCD只要遵守两个步骤即可:
- 创建对列(串行队列,并行队列)
- 将任务提交给队列
串行队列(同步提交,异步提交)
创建一个串行队列:
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
向队列提交任务,包括同步和异步:
dispatch_sync(queue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"线程一:%d",[NSThread isMainThread]); }); dispatch_sync(queue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"线程二:%d",[NSThread isMainThread]); }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"线程三:%d",[NSThread isMainThread]); }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"线程四:%d",[NSThread isMainThread]); });
上面的代码在串行队列中提交了四个任务,同步提交,在主线程中,异步提交,在分线程中。
因为是串行队列,打印的顺序是:线程一,线程二,线程三,线程四,一、二是主线程,三、四十是分线程
串行队列可以暂停队列和继续队列:
//暂停队列 dispatch_suspend(queue); //继续队列 dispatch_resume(queue);
并行队列(同步提交,异步提交)
并行队列我们不需要自己创建,系统为我们提供了方法:
获取并行队列:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
在并行队列中,也分为同步提交和异步提交,同步提交在主线程中,异步提交在分线程中。
同步提交的任务还是按照顺序执行,异步提交的任务,顺序不定。
dispatch_sync(queue, ^{ NSLog(@"任务一开始执行"); [NSThread sleepForTimeInterval:2]; NSLog(@"线程:%d",[NSThread isMainThread]); }); dispatch_sync(queue, ^{ NSLog(@"任务二开始执行"); [NSThread sleepForTimeInterval:2]; NSLog(@"线程:%d",[NSThread isMainThread]); }); dispatch_async(queue, ^{ NSLog(@"任务三开始执行"); [NSThread sleepForTimeInterval:2]; NSLog(@"线程:%d",[NSThread isMainThread]); }); dispatch_async(queue, ^{ NSLog(@"任务四开始执行"); [NSThread sleepForTimeInterval:2]; NSLog(@"线程:%d",[NSThread isMainThread]); });
任务一,任务二十同步提交,按照顺序执行,执行完后,执行三,四,因为三,四是异步提交,同时执行,顺序不定。
其它常用方法
获取主线程队列:
dispatch_queue_t mainQueue = dispatch_get_main_queue();
指定时间执行该代码块:
dispatch_after(<#dispatch_time_t when#>, <#dispatch_queue_t queue#>, <#^(void)block#>)
将代码以异步方式提交给指定队列,该队列底层的线程池将多次重复执行该代码块
dispatch_apply(<#size_t iterations#>, <#dispatch_queue_t queue#>, <#^(size_t)block#>)
将代码提交给指定队列,该队列底层的线程池控制在应用的某个生命周期内仅执行该函数一次
dispatch_once(<#dispatch_once_t *predicate#>, <#^(void)block#>)