手机开发 2016-11-04
GCD(Grand Central Dispatch)应该是我们开发中最常用到的多线程解决方案,是苹果公司专门为多核的并行运算提出的解决方案,是基于C语言的,提供了很多非常强大的函数。
1.会自动利用更多的CPU内核(从iPhone4s开始是双核,iPhone7系列是4核)。 2.会自动管理线程的创建、生命周期、销毁等,不需要写一句关于线程的代码。 3.将任务添加到队列中,GCD会自动从队列中将任务取出,放到对应的线程中执行。
1.简单点说一个APP就是一个进程,例如微信、迅雷都分别是一个进程。 2.一个进程可以拥有多条线程。当我们打开APP时系统会自动帮我们创建一条主线程,当我们要让APP干点别的事时,例如刷新数据,就要开启一条子线程来向服务器请求数据,所以一个进程可以拥有多条线程。(并不是让APP干什么事,都会开启子线程,这里只是为了解释方便,才这么说的。)
队列就是用来存放任务的,任务就是我们让APP干的事,例如下载图片,刷新数据等,都是任务。我们使用GCD,只要把任务放到队列中就可以了,系统会自动帮我们创建线程,调度任务。任务的调度原则遵行FIFO原则,就是哪个任务先放进队列中,就先执行。队列分为串行队列,和并行(并发)队列。 1.串行队列 : 就是队列里的任务必须一个一个往下执行。例如我们要执行A、B、C 三个任务,我们把这三个任务放到串行队列中,必须是A执行完,B才执行,B执行完C才执行。 创建串行队列有两种方法: (1)自定义队列 代码:
// 创建串行队列 dispatch_queue_t queue = dispatch_queue_create("doujiangyoutiao", DISPATCH_QUEUE_SERIAL); // 添加任务A dispatch_async(queue, ^{ NSLog(@"执行任务A"); }); // 添加任务B dispatch_async(queue, ^{ NSLog(@"执行任务B"); }); // 添加任务C dispatch_async(queue, ^{ NSLog(@"执行任务C"); });
日志
2016-11-04 14:00:06.546 TTTTTTTTTT[11059:128030] 执行任务A 2016-11-04 14:00:06.546 TTTTTTTTTT[11059:128030] 执行任务B 2016-11-04 14:00:06.547 TTTTTTTTTT[11059:128030] 执行任务C
1)“doujiangyoutiao”是这个队列的名字; 2)DISPATCH_QUEUE_SERIAL表示创建的是一条串行对列。 (2)主队列 dispatch_queue_t queue =dispatch_get_main_queue();
得到主队列,主队列是串行队列,主队列中的任务默认都在主线程中执行。 2.并行队列:就是队列里的任务可以一齐执行。还是举执行A、B、C 三个任务的例子。我们把三个任务放到并行队列中,这三个任务可以一起执行,所以不一定谁先下载完。串行队列里一定是A先下载完。 代码:
- (void)viewDidLoad { [super viewDidLoad]; // 创建并行队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 添加任务A dispatch_async(queue, ^{ NSLog(@"执行任务A"); }); // 添加任务B dispatch_async(queue, ^{ NSLog(@"执行任务B"); }); // 添加任务C dispatch_async(queue, ^{ NSLog(@"执行任务C"); }); }
每次打印的日志应该都不一样,有兴趣可以多试几次。
2016-11-04 14:09:03.871 TTTTTTTTTT[11356:131391] 执行任务B 2016-11-04 14:09:03.871 TTTTTTTTTT[11356:131393] 执行任务C 2016-11-04 14:09:03.871 TTTTTTTTTT[11356:131390] 执行任务A
创建并行队列有两种方法: (1)看上面代码得到全局并行队列,不需要我们创建,我们一般用这个。第一个参数表示这个队列的优先级 (DISPATCH_QUEUE_PRIORITY_HIGH、DISPATCH_QUEUE_PRIORITY_DEFAULT、DISPATCH_QUEUE_PRIORITY_LOW、DISPATCH_QUEUE_PRIORITY_BACKGROUND),用第二个就可以。第二个参数还没开发出来,没有用,默认写0即可。 (2)自定义队列 dispatch_queue_t queue=dispatch_queue_create("fuhang",DISPATCH_QUEUE_CONCURRENT);
"fuhang"为并发队列的名字,后面表示创建的队列为并行队列。
同步:会堵塞当前线程,队列里的任务执行完,任务所在的线程才会往下执行。其实说白了就是插队。 dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
第一个参数是队列,第二个参数是要往队列里添加的任务。
异步:不会堵塞当前线程。 dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
同上。 同步和异步就是用来判断是否要在当前线程的基础上创建新的线程。同步不会创建新的线程,队列里的任务在当前线程中执行,所以会堵塞当前线程。但是异步也不是一定会创建新的线程,这要根据CPU的使用情况来看,但是大多数情况会创建一个线程。