如果上一集您看的不尽兴,那这次的GCD一定不会让你失望,因为会满足你很多意想不到的需求。
GCD概念:纯C语言,提供非常多强大的函数,是目前苹果官网推荐的多线程开发方法,NSOperation便是基于GCD的封装。
GCD优势: GCD自动管理线程,提高CPU效率,操作起来更加简便、快捷。
GCD中的的两个核心:任务、队列 (在第一篇中的时候略有提到,遵守先进先出的原则)
任务的类型分为两种:同步任务和异步任务 (决定是否开启新的线程)
同步任务:只能在当前线程中执行任务,不能开启新的线程。
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
异步任务:能在新的线程中执行任务,能开启新的线程。
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
队列的类型分为两种:串行队列和并发队列 (主要决定任务的执行方式)
串行队列:按照任务的先后顺序执行 (比如你用迅雷下载 “大片” 一样,想先下载一个下来看其余的边看边下,这时需要把迅雷 的最多下载任务数设置成1,其余的任务都处在等在中,但当前的任务下载完,等待的任务在按照先后顺序执行)
使用 dispatch queue create() 函数创建串行队列
dispatch_queue_t queue = dispatch_queue_create(“队列的名称:https://teilim.com”, “队列的属性:DISPATCH_QUEUE_SERIAL”); /* 非ARC在不需要时手动需要释放其队列 */ dispatch_release(queue);
使用 dispatch get main_queue() 函数获得主队列 (是GCD自带的一种串行队列,在其队列执行的任务,都会放到主线程中执行)
dispatch_queue_t queue = dispatch_get_main_queue();
并发队列:可以让多个任务同时执行 (上次因为 “特殊时期”所以比较着急下载,这就一边写博客一边下载,反正时间也是很充裕,就干脆把最多下载任务数设置成了5,让五个任务一起执行下载,就是网速稍微的慢一点)
1.使用 dispatch queue create() 函数创建串行队列
dispatch_queue_t queue = dispatch_queue_create(“队列的名称:https://teilim.com”, “队列的属性:DISPATCH_QUEUE_CONCURRENT”); /* 非ARC在不需要时手动需要释放其队列 */ dispatch_release(queue);
2.使用 dispatch get global_queue() 函数获得全局的并发队列
dispatch_queue_t dispatch_get_global_queue( dispatch_queue_priority_t priority: 队列的优先级,unsigned long flags:0); /* 获得全局并发队列 */ dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); #define DISPATCH_QUEUE_PRIORITY_HIGH /* 高 */ #define DISPATCH_QUEUE_PRIORITY_DEFAULT /* 默认 */ #define DISPATCH_QUEUE_PRIORITY_LOW (-2) /* 低 */ #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN /* 后台 */
将同步函数、异步函数,串行队列、并发队列相互组合,观察其在个个情况下的执行效果。
- (void)syncSerial { /* 创建串行队列 */ dispatch_queue_t queue = dispatch_queue_create("https://teilim.com", DISPATCH_QUEUE_SERIAL); /* 将执行任务加入队列 */ dispatch_sync(queue, ^{ for (NSInteger i = 0; i<5; i++) { NSLog(@"已经下载欧美大片%lo次-----%@", i,[NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (NSInteger i = 0; i<5; i++) { NSLog(@"已经下载岛国大片%lo次-----%@", i,[NSThread currentThread]); } }); }
效果:只能当前线程执行任务,一个任务执行完毕,在执行下一个任务,按任务的排列顺序执行。
效果图如下:
- (void)syncConcurrent { /* 创建并发队列 */ dispatch_queue_t queue = dispatch_queue_create("https://teilim.com", DISPATCH_QUEUE_CONCURRENT); /* 将执行任务加入队列 */ dispatch_sync(queue, ^{ for (NSInteger i = 0; i<5; i++) { NSLog(@"已经下载欧美大片%lo次-----%@", i,[NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (NSInteger i = 0; i<5; i++) { NSLog(@"已经下载岛国大片%lo次-----%@", i,[NSThread currentThread]); } }); }
效果:只能当前线程执行任务,一个任务执行完毕,在执行下一个任务,按任务的排列顺序执行。
效果图如下:
- (void)asyncSerial { /* 创建串行队列 */ dispatch_queue_t queue = dispatch_queue_create("https://teilim.com", DISPATCH_QUEUE_SERIAL); /* 将任务加入队列 */ dispatch_async(queue, ^{ for (NSInteger i = 0; i<5; i++) { NSLog(@"已经下载欧美大片%lo次-----%@", i,[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (NSInteger i = 0; i<5; i++) { NSLog(@"已经下载岛国大片%lo次-----%@", i,[NSThread currentThread]); } }); }
效果:能开启新的线程,但是在串行队列中执行任务,按任务的排列顺序执行。
效果图如下:
- (void)asyncConcurrent { /* 创建并发队列 */ dispatch_queue_t queue = dispatch_queue_create("com.520it.queue", DISPATCH_QUEUE_CONCURRENT); /* 将任务加入队列 */ dispatch_async(queue, ^{ for (NSInteger i = 0; i<5; i++) { NSLog(@"已经下载欧美大片%lo次-----%@", i,[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (NSInteger i = 0; i<6; i++) { NSLog(@"已经下载岛国大片%lo次-----%@", i,[NSThread currentThread]); } }); }
效果:可以开启多个线程,多个线程中相互执行。
效果图如下: