GCD
GCD(GRAND CENTRAL DISPATCH),就是牛逼的中枢调度器。C语言写的,提供了多种函数。
1.任务和队列
GCD两个核心的概念就是任务和队列。 任务:执行什么操作的。 队列:专门来存放任务的。 GCD的使用很简单,也就是先把任务定制好,然后放在队列中,GCD会自动的将任务从队列中取出来,然后放到对应的线程中去执行,任务的取出遵循先进先出和后进后出的原则。
2.同步、异步
// 同步
dispatch_sync(<#dispatch_queue_t _Nonnull queue#>, <#^(void)block#>)
// 异步
dispatch_async(<#dispatch_queue_t _Nonnull queue#>, <#^(void)block#>)
queue:队列
block:任务
同步和异步的区别: 同步:只能在当前线程中执行任务,不具备开启新的线程的能力 异步:可以在新的线程中执行任务,具备开启新的线程的能力
3.串行队列、并发队列
并发队列:可以将多个任务并发的同时的执行,自动的开启多个线程同时执行任务。 串行队列:任务是一个接着一个的执行。
以上的四个术语的一些说明:关于同步异步,只是说明了有无开具新的线程的能力;而对串行和并发队列来说就是任务执行的方式。
4.GCD的基本使用
- 异步并发:
/**
异步+并发->会开启多条线程的,队列中任务是异步执行的
*/
- (void)wjAsyncConcurrent {
// 1.创建队列
// DISPATCH_QUEUE_CONCURRENT : 并发队列
dispatch_queue_t queue = dispatch_queue_create("com.wj.downLoad", DISPATCH_QUEUE_CONCURRENT);
// 2.定制任务->还将把任务添加到队列中
dispatch_async(queue, ^{
NSLog(@"异步+并发 1 : %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"异步+并发 2 : %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"异步+并发 3 : %@", [NSThread currentThread]);
});
/*
打印结果
异步+并发 1 : <NSThread: 0x600000070480>{number = 3, name = (null)}
异步+并发 3 : <NSThread: 0x600000070840>{number = 4, name = (null)}
异步+并发 2 : <NSThread: 0x600000070680>{number = 5, name = (null)}
*/
}
- 异步串行
/**
异步+串行->会开线程,开了一条线程,队列中的任务是串行执行的。
*/
- (void)wjAsyncSerial {
dispatch_queue_t queue = dispatch_queue_create("com.wj.download", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"异步+串行 1 : %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"异步+串行 2 : %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"异步+串行 3 : %@", [NSThread currentThread]);
});
/*
打印结果
异步+串行 1 : <NSThread: 0x60800006dd80>{number = 3, name = (null)}
异步+串行 2 : <NSThread: 0x60800006dd80>{number = 3, name = (null)}
异步+串行 3 : <NSThread: 0x60800006dd80>{number = 3, name = (null)}
*/
}
- 同步并发
/**
同步+并发->不会开线程,在主线程中执行,且任务是串行执行
*/
- (void)wjSyncConcurrent {
dispatch_queue_t queue = dispatch_queue_create("com.wj.downLoad", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
NSLog(@"同步+并发 1 : %@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"同步+并发 2 : %@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"同步+并发 3 : %@", [NSThread currentThread]);
});
/*
打印结果
同步+并发 1 : <NSThread: 0x608000261f80>{number = 1, name = main}
同步+并发 2 : <NSThread: 0x608000261f80>{number = 1, name = main}
同步+并发 3 : <NSThread: 0x608000261f80>{number = 1, name = main}
*/
}
- 同步串行
/**
同步+串行->不会开线程
*/
- (void)wjSyncSerial {
dispatch_queue_t queue = dispatch_queue_create("com.wj.download", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"同步+串行 1 : %@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"同步+串行 2 : %@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"同步+串行 3 : %@", [NSThread currentThread]);
});
/*
打印结果
同步+串行 1 : <NSThread: 0x600000077180>{number = 1, name = main}
同步+串行 2 : <NSThread: 0x600000077180>{number = 1, name = main}
同步+串行 3 : <NSThread: 0x600000077180>{number = 1, name = main}
*/
}
- 线程开多少的问题?
/**
获得全局并发队列
*/
- (void)wjGetGlobleConcurrentQueue {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSLog(@"异步+并发 1 : %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"异步+并发 2 : %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"异步+并发 3 : %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"异步+并发 4 : %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"异步+并发 5 : %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"异步+并发 6 : %@", [NSThread currentThread]);
});
/*
打印结果->可以显示出,并不是有多少个任务就创建多少个线程,而是有系统自己决定的。
异步+并发 3 : <NSThread: 0x60000026c700>{number = 5, name = (null)}
异步+并发 4 : <NSThread: 0x6080002688c0>{number = 6, name = (null)}
异步+并发 1 : <NSThread: 0x608000268c80>{number = 3, name = (null)}
异步+并发 2 : <NSThread: 0x608000268a80>{number = 4, name = (null)}
异步+并发 5 : <NSThread: 0x60000026c3c0>{number = 7, name = (null)}
异步+并发 6 : <NSThread: 0x60000026c700>{number = 5, name = (null)}
*/
}