今天风超大的,把我人都快吹走了,但是我还是回来来。。。啦啦啦,长话短说,下面为大家准备了GCD的深入了解。大家可以复制到自己的Xcode里面运行下了。然后仔细看看这些介绍,多敲几遍。其实很简单的,一个并发 一个串行队列。。。就像我们走路一样,3个人走一排角并发 ,把3个人拍好队一个个走,就是串行队列。。哈哈,是不是很有意思呢?
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super
viewDidLoad];
//------------------ GCD ---------------------
//1.什么是GCD?
//Grand Central Dispatch (大中央调度),纯C语言,提供了非常多强大的函数
//2. GCD的优势
//2.1 GCD是苹果公司为多核的并行运算提出的解决方法
//2.2 GCD会自动利用更多地CPU内核(双核,四核)
//2.3 GCD会自动管理线程的生命周期(包括,创建线程,调度任务,销毁线程)
//2.4 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码
// ----------------任务和队列-------------------------
//GCD中又两个核心概念
// 1. 任务 :执行什么操作
// 2. 队列 :用来存放任务
//GCD的使用就两个步骤
// 1. 定制队列
// 2. 确定想做的事情
//将任务添加到队列中,GCD会自动将队列中的任务取出,放到对应的线程中执行,任务的取出遵循队列的FIFO原则:先进先出,后进后出
// ------------
执行任务----------------
//1.GCD中有两个用来执行任务的函数
//说明:
把右边的参数(任务)提交给左边的参数(队列)中执行
//(1) 用同步的方式执行任务 dispatch_sync(dispatch_queue_t queue, <#^(void)block#>)
//(2) 用异步的方式执行任务dispatch_async(dispatch_queue_t queue, <#^(void)block#>)
//2. 同步和异步的区别
//同步:
在当前线程中执行
//异步:
在另一条线程中执行
// -------------
队列 -----------------------
// 1. 队列的类型
//1.1 并发队列
(Concurrent Dispatch Queue)可以让多个任务并发执行(自动开启多个线程同时执行任务),并发功能只由在异步函数(dispatch_async)下才有效
//1.2 串行队列
(Serial Dispatch Queue)
让任务一个接着一个执行
// 同步,异步,并发,串行
// 同步和异步决定了要不要开启新线程
// 同步:
在当前线程中执行任务,不具备开启新线程的能力
// 异步:
在新德线程中执行任务,具备开启新线程的能力
// 并发和串行决定了任务的执行方式
// 并发:
多个任务并发执行
// 串行:
一个任务执行完毕后,再执行下一个任务
//--------------------
串行队列 -------------------
//GCD中获取串行队列有两种方法
//1. dispatch_queue_create(<#const char *label#>, <#dispatch_queue_attr_t attr#>) //队列名称,
队列属性,一般为NULL
//2. dispatch_queue_t queue = dispatch_get_main_queue(),取到主队列,
主队列是GCD自带的一种特殊队列,
放在主队列中得任务,都会放到主线程中执行。
// -----------------
并发队列 -------------------
// GCD默认已经提供了全局的并发队列,
供整个应用使用,不需要手动创建
// dispatch_queue_t queue = dispatch_get_global_queue(<#long identifier#>, <#unsigned long flags#>)
第一个参数为优先级, 第二个参数为保留参数,给以后使用的,传0即可。
// ------------
总结 --------------------
// 同步函数不具备开启线程的能力,
无论什么队列都不会开启线程。
// 异步函数具备开启线程的能力,
开启几条线程由队列决定(串行队列只会开启一条新德线程,并发队列会开启多条线程)
// -----------
补充 --------------------
//凡是函数中,各种函数名中带有create\copy\new\retain等字眼,都需要在不需要使用这个数据的时候进行release。
//GCD的数据类型在ARC的环境下不需要再做release。
//CF(core Foundation)的数据类型在ARC环境下还是需要做release。
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//[self test1];
// [self test2];
// [self test3];
[self
test4];
}
// 在同步函数中的串行队列中添加任务,
不会开辟新线程
-(void)test1
{
//1. 创建串行队列 _t _ref C语言的数据类型
// 参数1 :
队列的名称
// 参数2 :
队列的属性 一般填NULL,表示创建串行队列,
// 参数2
中填 DISPATCH_QUEUE_SERIAL 创建串行队列
// DISPATCH_QUEUE_CONCURRENT
创建并行队列
dispatch_queue_t queue =
dispatch_queue_create("Serial Queue",
NULL);
dispatch_sync(queue, ^{
NSLog(@"下载任务1,curThread = %@",[NSThread
currentThread]);
[NSThread
sleepForTimeInterval:2];
});//在这,要等到任务执行完成才会接到执行
NSLog(@"111");
dispatch_sync(queue, ^{
NSLog(@"下载任务2,curThread = %@",[NSThread
currentThread]);
});
NSLog(@"222");
dispatch_sync(queue, ^{
NSLog(@"下载图片任务3,currThread = %@",[NSThread
currentThread]);
});
NSLog(@"333");
}
//在同步函数中的并行队列中添加任务,
不会开辟新线程,并发的功能无效
-(void)test2
{
//1. 取到并行队列,在iOS中,系统为每一个应用程序已经准备了一天全局队列,该全局队列为并行队列。
// 参数1 :
队列的优先级, 一般取默认优先级
// 参数2 :
保留参数,填0
dispatch_queue_t queue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);
dispatch_sync(queue, ^{
NSLog(@"下载图片任务1, curThread = %@",[NSThread
currentThread]);
[NSThread
sleepForTimeInterval:2];
});
NSLog(@"111");
dispatch_sync(queue, ^{
NSLog(@"下载图片任务2,curThread = %@",[NSThread
currentThread]);
});
NSLog(@"222");
dispatch_sync(queue, ^{
NSLog(@"下载图片任务3,curThread = %@",[NSThread
currentThread]);
});
NSLog(@"333");
}
/**
* 在异步函数中的串行队列中添加任务,
会开辟新线程,但是只会开辟一个线程。
*/
- (void)test3
{
// 1. 创建串行队列
dispatch_queue_t queue =
dispatch_queue_create("Serial Queue",
DISPATCH_QUEUE_SERIAL);
//2. 通过异步函数在串行队列中添加任务
dispatch_async(queue, ^{
NSLog(@"下载图片任务1 , curThread = %@",
[NSThread
currentThread]);
[NSThread
sleepForTimeInterval:2];
});
NSLog(@"1111");
dispatch_async(queue, ^{
NSLog(@"下载图片任务2 , curThread = %@",
[NSThread
currentThread]);
});
NSLog(@"2222");
dispatch_async(queue, ^{
NSLog(@"下载图片任务3 , curThread = %@",
[NSThread
currentThread]);
[NSThread
sleepForTimeInterval:2];
});
NSLog(@"333");
}
/**
* 在异步函数中的并行队列中添加任务,
可能会开辟多个新线程
*/
- (void)test4
{
//1 .创建并行队列
dispatch_queue_t queue =
dispatch_queue_create("Concurrent Queue",
DISPATCH_QUEUE_CONCURRENT);
//2. 通过异步函数在并行队列中添加任务
dispatch_async(queue, ^{
[NSThread
sleepForTimeInterval:2];
NSLog(@"下载图片任务1 , curThread = %@",
[NSThread
currentThread]);
});
NSLog(@"1111");
dispatch_async(queue, ^{
NSLog(@"下载图片任务2 , curThread = %@",
[NSThread
currentThread]);
});
NSLog(@"2222");
dispatch_async(queue, ^{
NSLog(@"下载图片任务3 , curThread = %@",
[NSThread
currentThread]);
// [NSThread sleepForTimeInterval:2];
});
NSLog(@"333");
}
@end