GCD概述:
OC:
/*
GCD:Grand Central Dispatch 牛X的中枢调度器,C语言编写
GCD:自动管理线程的生命周期,(创建, 调度任务, 销毁线程)
任务:block (1.定制任务)
队列:queue (2.任务添加到队列)
GCD自动从队列queue中取出任务block执行,遵循FIFO原则,先进先出
任务block执行方式:
同步的(synchronous ['sɪŋkrənəs]):不能开新线程
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
异步的(asynchronous [e'sɪŋkrənəs]):能开新线程
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
队列queue:
并发队列(Concurrent Dispatch Queue):
[DISPATCH_QUEUE_CONCURRENT];
让多个任务并发执行,自动开启多个线程同时执行任务;
该功能只在异步函数(dispatch_async)下有效;
串行队列(Serial Dispatch Queue):
[DISPATCH_QUEUE_SERIAL];
让任务顺序执行;
队列queue的创建:
并发队列:
方式1.dispatch_queue_create(const char *label, dispatch_queue_attr_a attr)
label:表示该队列的名字(标识), C语言中的字符串,创建的时候直接"abcde";
attr:表示队列属性,设置并发or串行,此处使用并发(DISPATCH_QUEUE_CONCURRENT)
方式2:获取全局并发队列
dispatch_get_global_queue(dispatch_queue_priority_t priority, unsigned long flags);
priority:队列的优先级(高,默认,低,后台)
flags:此参数暂时无用,用0即可
串行队列:
方式1.dispatch_queue_create(const char *label, dispatch_queue_attr_a attr)
label:表示该队列的名字(标识);
attr:表示队列属性,设置并发or串行,此处使用串行(DISPATCH_QUEUE_SERIAL or NULL)
方式2:使用主队列,与主线程相关联的队列
主队列是GCD自带的一种特殊的串行队列;该队列中的任务,都会在主线程中执行;
dispatch_get_main_queue();
*/
相关练习:
#pragma mark - 并发队列,同步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)concurrentSync {
// A.创建并发队列concurrentQueue:
char *queueName = "ConcurrentQueue";
dispatch_queue_t concurrentQueue = dispatch_queue_create(queueName, DISPATCH_QUEUE_CONCURRENT);
// B.创建任务block
// 方式一: 定义一个block类型,命名为TestBlock1,然后只用该类型声明变量block1
// 1.定义一个block的类型,返回值void,参数为空,命名为Block1,(类似于 int),
typedef void (^TestBlock1)();
// 2.使用Block1类型定义一个变量block, 同时做赋值操作,赋值的内容为后面的代码段(^{...})
TestBlock1 block1 = ^{
// 这是里block中的操作
for (int i = 0; i < 5; i++) {
NSLog(@"---block1---%@", [NSThread currentThread]);
}
};
// 方式二: 直接定义一个名为block的block2变量
void (^block2)() = ^{
// 这是里block中的操作
for (int i = 0; i < 5; i++) {
NSLog(@"---block2---%@", [NSThread currentThread]);
}
};
// C.给并发队列concurrentQueue,添加同步任务dispatch_sync
// 方式1: block1变量
dispatch_sync(concurrentQueue, block1);
// 方式2: block2变量
dispatch_sync(concurrentQueue, block2);
// 方式3: 直接添加block
dispatch_sync(concurrentQueue, ^{
// 这是里block中的操作
for (int i = 0; i < 5; i++) {
NSLog(@"---block--3---%@", [NSThread currentThread]);
}
});
}
#pragma mark - 并发队列,异步任务: 开启新线程,任务并发执行
- (void)concurrentAsync {
// 1.创建并发队列 DISPATCH_QUEUE_CONCURRENT
char *queueName = "ConcurrentQueue";
dispatch_queue_t concurrentQueue = dispatch_queue_create(queueName, DISPATCH_QUEUE_CONCURRENT);
// 2.创建任务block
typedef void (^TestBlock)();
TestBlock block = ^{
// 这是里block中的操作
for (int i = 0; i < 5; i++) {
NSLog(@"---block1---%@", [NSThread currentThread]);
}
};
void (^block2)() = ^{
// 这是里block中的操作
for (int i = 0; i < 5; i++) {
NSLog(@"---block2---%@", [NSThread currentThread]);
}
};
// 3.并发队列concurrent,添加异步任务async;
dispatch_async(concurrentQueue, block);
dispatch_async(concurrentQueue, block2);
dispatch_async(concurrentQueue, ^{
// 这是里block中的操作
for (int i = 0; i < 5; i++) {
NSLog(@"---3---%@", [NSThread currentThread]);
}
});
}
#pragma mark - 全局队列,同步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)globalSync {
//全局队列的优先级
#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
typedef long dispatch_queue_priority_t;
// 1.获取全局队列 DISPATCH_QUEUE_PRIORITY_DEFAULT or 0 都可以
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 2.创建任务block
typedef void (^TestBlock1)();
TestBlock1 block1 = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block1---%@", [NSThread currentThread]);
}
};
void (^block2)() = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block2---%@", [NSThread currentThread]);
}
};
// 3.给全局队列globalQueue,添加同步任务dispatch_sync
dispatch_sync(globalQueue, block1);
dispatch_sync(globalQueue, block2);
dispatch_sync(globalQueue, ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block--3---%@", [NSThread currentThread]);
}
});
}
#pragma mark - 全局队列,异步任务: 开启新线程,任务并发执行;
- (void)globalAsync {
// 1.获取全局队列 DISPATCH_QUEUE_PRIORITY_DEFAULT or 0 都可以
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
// 2.创建任务
typedef void (^TestBlock)();
TestBlock block = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block1---%@", [NSThread currentThread]);
}
};
void (^block2)() = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block2---%@", [NSThread currentThread]);
}
};
// 3.全局队列globalQueue,添加异步任务;
dispatch_async(globalQueue, block);
dispatch_async(globalQueue, block2);
dispatch_async(globalQueue, ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---3---%@", [NSThread currentThread]);
}
});
}
#pragma mark - 串行队列,同步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)serialSync {
char *queueName = "SerialQueue";
// 串行队列 DISPATCH_QUEUE_SERIAL or NULL
dispatch_queue_t serialQueue = dispatch_queue_create(queueName, DISPATCH_QUEUE_SERIAL);
// 创建任务block
typedef void (^TestBlock1)();
TestBlock1 block1 = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block1---%@", [NSThread currentThread]);
}
};
void (^block2)() = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block2---%@", [NSThread currentThread]);
}
};
// 给串行队列serialQueue,添加同步任务dispatch_sync
dispatch_sync(serialQueue, block1);
dispatch_sync(serialQueue, block2);
dispatch_sync(serialQueue, ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block--3---%@", [NSThread currentThread]);
}
});
}
#pragma mark - 串行队列,异步任务: 开启新线程,任务按添加顺序依次执行;
- (void)serialAsync {
// 1.创建队列queue
char *queueName = "SerialQueue";
dispatch_queue_t serialQueue = dispatch_queue_create(queueName, NULL);
// 2.创建任务block
typedef void (^TestBlock1)();
TestBlock1 block1 = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block1---%@", [NSThread currentThread]);
}
};
void (^block2)() = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block2---%@", [NSThread currentThread]);
}
};
// 3.串行队列serialQueue, 添加异步任务
dispatch_async(serialQueue, block1);
dispatch_async(serialQueue, block2);
dispatch_async(serialQueue, ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block--3---%@", [NSThread currentThread]);
}
});
}
#pragma mark - 主队列, 同步任务: 死锁
- (void)mainSync {
NSLog(@"%s", "主队列mai zhuduilie, 同步任务sync tongburenwu, 会造成死锁 huizaochengsisuo");
// 1.获得主队列main
dispatch_queue_t mainQueue = dispatch_get_main_queue();
// 2.创建任务block
typedef void (^TestBlock1)();
TestBlock1 block1 = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block1---%@", [NSThread currentThread]);
}
};
void (^block2)() = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block2---%@", [NSThread currentThread]);
}
};
// 3.给主队列mainQueue,添加同步任务dispatch_sync
dispatch_sync(mainQueue, block1);
dispatch_sync(mainQueue, block2);
dispatch_sync(mainQueue, ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block--3---%@", [NSThread currentThread]);
}
});
// 死锁导致block中的内容都不会执行
}
/*
GCD Queue 分为三种:
1,The main queue:主队列,主线程就是在个队列中。
2,Global queues: 全局并发队列。
3,用户队列:是用函数 dispatch_queue_create 创建的自定义队列
dispatch_sync 和 dispatch_async 区别:
dispatch_async(queue,block) async 异步队列,dispatch_async 函数会立即返回, block会在后台异步执行。
dispatch_sync(queue,block) sync 同步队列,dispatch_sync 函数不会立即返回,及阻塞当前线程,等待block同步执行完成。
分析:
在主线程中,即dispatch_get_main_queue()中,执行到sync时向dispatch_get_main_queue()插入同步block1.
sync会等到后面block1执行完成才返回,sync又在dispatch_get_main_queue() 队列中,它是串行队列,sync是后加入的,
前一个是主线程,所以sync想执行block必须等待主线程执行完成,主线程等待sync返回,去执行后续内容。
造成死锁,sync等待main执行完成,mian等待sync函数返回。
*/
#pragma mark - 主队列,异步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)mainAsync {
// 1.获取主队列main
dispatch_queue_t mainQueue = dispatch_get_main_queue();
// 2.创建任务block
typedef void (^TestBlock1)();
TestBlock1 block1 = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block1---%@", [NSThread currentThread]);
}
};
void (^block2)() = ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block2---%@", [NSThread currentThread]);
}
};
// 3.给主队列mainQueue,添加异步任务dispatch_async
dispatch_async(mainQueue, block1);
dispatch_async(mainQueue, block2);
dispatch_async(mainQueue, ^{
for (int i = 0; i < 5; i++) {
NSLog(@"---block--3---%@", [NSThread currentThread]);
}
});
}
#pragma mark -
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
/***********************************************************/
// 定义block的两种方式之一:
// 定义
// 参考范例,返回值int,参数(int, int)(没有参数名,匿名),名称Test
typedef int (^Test1)(int, int);
// 使用Test初始化一个变量test
Test1 test1 ;
// 实现
test1 = ^(int x, int y) {
return x + y;
};
// 调用
int result = test1(1, 2); //result = 3;
NSLog(@"%d", result);
/////////
// 初始化变量,实现,同时进行
Test1 test = ^(int x, int y) {
return x + y;
};
// 调用
NSLog(@"%d", test(100, 200));
/***********************************************************/
// 定义block的两种方式之二:
// 定义,实现,合并进行
// 直接定义一个变量test2,参数(int, int)(没有参数名,匿名),名称Test
int (^test2)(int, int) = ^(int x, int y){
return x + y;
};
NSLog(@"%d", test2(10, 20)); //result = 30;
/***********************************************************/
}
Swift 3.0:
/**
GCD:Grand Central Dispatch 牛X的中枢调度器
GCD:自动管理线程的生命周期,(创建, 调度任务, 销毁线程)
任务:闭包closure or DispatchWorkItem
队列:DispatchQueue
GCD自动从队列中取出任务执行,遵循FIFO原则,先进先出
任务执行方式:
同步(synchronous ['sɪŋkrənəs]):不能开新线程
DispatchQueue.global().sync {
// 同步执行
}
异步(asynchronous [e'sɪŋkrənəs]):能开新线程
DispatchQueue.global().async {
// code
DispatchQueue.main.async {
// 主线程中
}
}
队列DispatchQueue:
DispatchQueue的默认初始化方法创建的就是一个串行队列,如果要创建并发的队列,在attributes中声明concurrent。
label:表示该队列的名字(标识);
attributes:表示队列属性,默认为串行,
同步队列
let serialQueue = DispatchQueue(label: "QueueName")
让任务顺序执行;
主队列
let mainQueue = DispatchQueue.main
并发队列
let concurrentQueue = DispatchQueue(label: "QueueName", attributes: .concurrent)
让多个任务并发执行,自动开启多个线程同时执行任务;
全局并发队列
let globalQueue = DispatchQueue.global(qos: .default)
let globalQueue = DispatchQueue.global()
// global 有默认的参数default, 如需改变优先级,则输入对应的枚举即可
*/
相关练习:
// MARK: - 并发Concurrent,同步sync,没有开启新线程,任务在主队列main依次执行;
func concurrentSync() -> Void {
// 创建并发队列
let concurrentQueue = DispatchQueue(label: "ConcurrentQueue", attributes: .concurrent)
// 任务类型
typealias Task = () -> Void
// Task类型的变量
let task1: Task
// 任务实现
task1 = {
print("concurrentSync task1...", Thread.current)
}
let task2: () -> Void = {
print("concurrentSync task2...", Thread.current)
}
// 并发队列Concurrent,同步sync执行
concurrentQueue.sync(execute: task1) // main
concurrentQueue.sync(execute: task2) // main
concurrentQueue.sync {
print("concurrentSync task3...", Thread.current)
} // main
}
// MARK: - 并发Concurrent,异步async,开启新线程,任务并发执行;
func concurrentAsync() -> Void {
// 队列(并发concurrent)
let concurrentQueue = DispatchQueue(label: "ConcurrentQueue", attributes: .concurrent)
// 任务(闭包 or block)
typealias Task = () -> Void
let task1: Task = {
print("concurrentAsync-task1...", Thread.current)
}
let task2: () -> Void = {
print("concurrentAsync-task2...", Thread.current)
}
// 并发,异步
concurrentQueue.async(execute: task1) // new 1
concurrentQueue.async(execute: task2) // new 2
concurrentQueue.async {
print("concurrentAsync-task3...", Thread.current)
} // new 3
}
// MARK: - 全局global,同步sync,没有开启新线程,任务在主队列main依次执行;
func globalSync() -> Void {
typealias Task = () -> Void
let task1: Task = {
print("globalSync...task1...", Thread.current)
}
let task2: () -> Void = {
print("globalSync...task2...", Thread.current)
}
/**
* global优先级的新旧枚举值对应
* DISPATCH_QUEUE_PRIORITY_HIGH: .userInitiated
* DISPATCH_QUEUE_PRIORITY_DEFAULT: .default
* DISPATCH_QUEUE_PRIORITY_LOW: .utility
* DISPATCH_QUEUE_PRIORITY_BACKGROUND: .background
*/
// public class func global(qos: DispatchQoS.QoSClass = default) -> DispatchQueue
// global 有默认的参数default, 如需改变优先级,则输入对应的枚举即可
DispatchQueue.global(qos: .userInteractive).sync(execute: task1) // main 1
DispatchQueue.global(qos: .userInteractive).sync(execute: task2) // main 2
DispatchQueue.global(qos: .userInteractive).sync {
print("globalSync...task3...", Thread.current)
} // main 3
}
// MARK: - 全局global,异步async,开启新线程,任务并发执行;
func globalAsync() -> Void {
typealias Task = () -> Void
let task1: Task = {
print("globalAsync...task1...", Thread.current)
}
let task2: Task = {
print("globalAsync...task2...", Thread.current)
}
DispatchQueue.global().async(execute: task1) // new 1
DispatchQueue.global().async(execute: task2) // new 2
DispatchQueue.global().async {
print("globalAsync...task3...", Thread.current)
} // new 3
}
/// 线程任务
typealias ThreadTask = () -> Void
// MARK: - 串行serial,同步sync,没有开启新线程,任务按顺序执行;
func serialSync() -> Void {
// 队列
let serialQueue = DispatchQueue(label: "SerialQueue")
// 任务
let task1: ThreadTask = {
print("serialSync...task1...", Thread.current)
}
let task2: ThreadTask = {
print("serialSync...task2...", Thread.current)
}
let task3: ThreadTask = {
print("serialSync...task3...", Thread.current)
}
// 串行,同步
serialQueue.sync(execute: task1) // main 1
serialQueue.sync(execute: task2) // main 2
serialQueue.sync(execute: task3) // main 3
}
// MARK: - 串行Serial,异步async,开启新线程,任务按顺序执行
func serialAsync() -> Void {
// 队列
let serialQueue = DispatchQueue(label: "SerialQueue")
// 任务
let task1: ThreadTask = {
print("serialSync...task1...", Thread.current)
}
let task2: ThreadTask = {
print("serialSync...task2...", Thread.current)
}
let task3: ThreadTask = {
print("serialSync...task3...", Thread.current)
}
// 串行,异步
serialQueue.async(execute: task1) // new 1
serialQueue.async(execute: task2) // new 2
serialQueue.async(execute: task3) // new 3
}
// MARK: - 主队列main,同步sync,死锁
func mainSync() -> Void {
// 队列
let mainQueue = DispatchQueue.main
// 任务
let task1: ThreadTask = {
print("serialSync...task1...", Thread.current)
}
let task2: ThreadTask = {
print("serialSync...task2...", Thread.current)
}
let task3: ThreadTask = {
print("serialSync...task3...", Thread.current)
}
// 主队列,同步
mainQueue.sync(execute: task1) // 死锁 x
mainQueue.sync(execute: task2) // x
DispatchQueue.main.sync(execute: task3) // x
}
// MARK: - 主队列main,异步async,不开启新线程,任务依次执行
func mainAsync() -> Void {
let mainQueue = DispatchQueue.main
let task1: ThreadTask = {
print("serialSync...task1...", Thread.current)
}
let task2: ThreadTask = {
print("serialSync...task2...", Thread.current)
}
let task3: ThreadTask = {
print("serialSync...task3...", Thread.current)
}
mainQueue.async(execute: task1) // main 1
mainQueue.async(execute: task2) // main 2
DispatchQueue.main.async(execute: task3) // main 3
}
// MARK: - 闭包测试
func closureTest() -> Void {
// 闭包回顾
/***********************************************************/
// 定义, 有3+参, 有返回值
typealias Test = (Int, Int, Int) -> Int
// 声明变量test1
var test1: Test
// 实现
test1 = { x, y, z in
// 闭包中的操作
print("有3+参, 有返回值 test1...111")
return x + y + z
}
// 调用
print("test1...", test1(1, 2, 3))
// 声明,实现
let test2: Test = {
// 闭包中的操作
print("有3+参, 有返回值 test2...222")
return $0 + $1 + $2
}
// 调用
print("test2...", test2(10, 20, 30))
/***********************************************************/
// 定义, 有2参, 有返回值
var test3: (Int, Int) -> Int
// 实现
test3 = (+)
// 调用
print("有2参, 有返回值 test3...", test3(100, 200))
/***********************************************************/
// 定义,无参,有返回值
var test4: () -> Int
// 实现
test4 = {
// 闭包中的操作
print("无参,有返回值 test4... 444")
return 12345
}
// 调用
print("test4...", test4())
/***********************************************************/
// 定义,无参,无返回值
let test5: () -> Void = {
// 相关操作
print("无参,有返回值 test5... 555")
}
test5()
/***********************************************************/
}
参考资料:
http://www.jianshu.com/p/fc78dab5736f
http://www.jianshu.com/p/28044b17f94b
https://www.logcg.com/archives/2040.html
https://github.com/future-challenger/Swift3.0/blob/master/GCD/README.md
https://my.oschina.net/doxing/blog/618132
http://v.youku.com/v_show/id_XMTU5MDg1MTE0NA==.html
http://v.youku.com/v_show/id_XMTU5MDg0OTY1Mg==.html