开始GCD之前我们先来了解下任务和队列的概念
任务
任务在程序里面可以理解为你写的一段代码, 执行任务就是运行代码,关键在于如何执行任务
这里就有同步执行和异步执行的概念了
-
同步执行(sync):
1、同步添加任务到指定的队列中,在添加的任务执行结束之前,会一直等待,直到队列里面的任务完成之后再继续执行
2、只能在当前线程中执行任务,不具备开启新线程的能力 -
异步执行(async):
1、异步添加任务到指定的队列中,它不会做任何等待,可以继续执行任务
2、可以在新的线程中执行任务,具备开启新线程的能力
队列(Dispatch Queue)
队列.png串行队列 (Serial Dispatch Queue)
串行队列.png- 每次只有一个任务被执行。让任务一个接着一个地执行。(只开启一个线程,一个任务执行完毕后,再执行下一个任务)
并行队列(Concurrent Dispatch Queue)
并行队列.png- 可以让多个任务并发(同时)执行。(可以开启多个线程,并且同时执行任务)
GCD 的创建和使用
// 串行队列
dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.serial", DISPATCH_QUEUE_SERIAL);
// 并行队列
dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.concurrent", DISPATCH_QUEUE_CONCURRENT);
//全局队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//主队列
dispatch_queue_t queue = dispatch_get_main_queue();
//同步执行
dispatch_sync(queue, ^{
});
//异步执行
dispatch_async(queue, ^{
});
上面说了4种队列,2种执行方式,那么他们的组合肯定有多种,来写点代码运行看看效果吧
1、 同步执行串行队列
NSLog(@"--- begin ---");
dispatch_queue_t serialQueue = dispatch_queue_create("com.example.gcd.serial", DISPATCH_QUEUE_SERIAL);
for (NSInteger i = 0; i < 10; i++) {
dispatch_sync(serialQueue, ^{
NSLog(@"%ld, 当前线程 : %@", i, [NSThread currentThread]);
});
}
NSLog(@"--- end ---");
日志打印
2019-05-14 16:03:01.382002+0800 GCDDemo[5717:153795] --- begin ---
2019-05-14 16:03:01.382222+0800 GCDDemo[5717:153795] 0, 当前线程 : <NSThread: 0x6000023313c0>{number = 1, name = main}
2019-05-14 16:03:01.382349+0800 GCDDemo[5717:153795] 1, 当前线程 : <NSThread: 0x6000023313c0>{number = 1, name = main}
2019-05-14 16:03:01.382464+0800 GCDDemo[5717:153795] 2, 当前线程 : <NSThread: 0x6000023313c0>{number = 1, name = main}
2019-05-14 16:03:01.382563+0800 GCDDemo[5717:153795] 3, 当前线程 : <NSThread: 0x6000023313c0>{number = 1, name = main}
2019-05-14 16:03:01.382659+0800 GCDDemo[5717:153795] 4, 当前线程 : <NSThread: 0x6000023313c0>{number = 1, name = main}
2019-05-14 16:03:01.382785+0800 GCDDemo[5717:153795] 5, 当前线程 : <NSThread: 0x6000023313c0>{number = 1, name = main}
2019-05-14 16:03:01.382879+0800 GCDDemo[5717:153795] 6, 当前线程 : <NSThread: 0x6000023313c0>{number = 1, name = main}
2019-05-14 16:03:01.382971+0800 GCDDemo[5717:153795] 7, 当前线程 : <NSThread: 0x6000023313c0>{number = 1, name = main}
2019-05-14 16:03:01.383061+0800 GCDDemo[5717:153795] 8, 当前线程 : <NSThread: 0x6000023313c0>{number = 1, name = main}
2019-05-14 16:03:01.395531+0800 GCDDemo[5717:153795] 9, 当前线程 : <NSThread: 0x6000023313c0>{number = 1, name = main}
2019-05-14 16:03:01.395652+0800 GCDDemo[5717:153795] --- end ---
结果分析:依次执行, 没有开辟新线程
2、同步执行并行队列
NSLog(@"--- begin ---");
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.example.gcd.serial", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger i = 0; i < 10; i++) {
dispatch_sync(concurrentQueue, ^{
NSLog(@"%ld, 当前线程 : %@", i, [NSThread currentThread]);
});
}
NSLog(@"--- end ---");
2019-05-14 16:04:34.245949+0800 GCDDemo[5739:154761] --- begin ---
2019-05-14 16:04:34.246151+0800 GCDDemo[5739:154761] 0, 当前线程 : <NSThread: 0x60000055d3c0>{number = 1, name = main}
2019-05-14 16:04:34.246264+0800 GCDDemo[5739:154761] 1, 当前线程 : <NSThread: 0x60000055d3c0>{number = 1, name = main}
2019-05-14 16:04:34.246373+0800 GCDDemo[5739:154761] 2, 当前线程 : <NSThread: 0x60000055d3c0>{number = 1, name = main}
2019-05-14 16:04:34.246484+0800 GCDDemo[5739:154761] 3, 当前线程 : <NSThread: 0x60000055d3c0>{number = 1, name = main}
2019-05-14 16:04:34.246593+0800 GCDDemo[5739:154761] 4, 当前线程 : <NSThread: 0x60000055d3c0>{number = 1, name = main}
2019-05-14 16:04:34.246705+0800 GCDDemo[5739:154761] 5, 当前线程 : <NSThread: 0x60000055d3c0>{number = 1, name = main}
2019-05-14 16:04:34.246801+0800 GCDDemo[5739:154761] 6, 当前线程 : <NSThread: 0x60000055d3c0>{number = 1, name = main}
2019-05-14 16:04:34.246891+0800 GCDDemo[5739:154761] 7, 当前线程 : <NSThread: 0x60000055d3c0>{number = 1, name = main}
2019-05-14 16:04:34.246982+0800 GCDDemo[5739:154761] 8, 当前线程 : <NSThread: 0x60000055d3c0>{number = 1, name = main}
2019-05-14 16:04:34.258913+0800 GCDDemo[5739:154761] 9, 当前线程 : <NSThread: 0x60000055d3c0>{number = 1, name = main}
2019-05-14 16:04:34.259039+0800 GCDDemo[5739:154761] --- end ---
结果分析: 同上
3、同步执行全局队列
NSLog(@"--- begin ---");
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (NSInteger i = 0; i < 10; i++) {
dispatch_sync(globalQueue, ^{
NSLog(@"%ld, 当前线程 : %@", i, [NSThread currentThread]);
});
}
NSLog(@"--- end ---");
2019-05-14 16:06:44.980750+0800 GCDDemo[5767:155906] --- begin ---
2019-05-14 16:06:44.981023+0800 GCDDemo[5767:155906] 0, 当前线程 : <NSThread: 0x6000016993c0>{number = 1, name = main}
2019-05-14 16:06:44.981168+0800 GCDDemo[5767:155906] 1, 当前线程 : <NSThread: 0x6000016993c0>{number = 1, name = main}
2019-05-14 16:06:44.981307+0800 GCDDemo[5767:155906] 2, 当前线程 : <NSThread: 0x6000016993c0>{number = 1, name = main}
2019-05-14 16:06:44.981410+0800 GCDDemo[5767:155906] 3, 当前线程 : <NSThread: 0x6000016993c0>{number = 1, name = main}
2019-05-14 16:06:44.981526+0800 GCDDemo[5767:155906] 4, 当前线程 : <NSThread: 0x6000016993c0>{number = 1, name = main}
2019-05-14 16:06:44.981640+0800 GCDDemo[5767:155906] 5, 当前线程 : <NSThread: 0x6000016993c0>{number = 1, name = main}
2019-05-14 16:06:44.981738+0800 GCDDemo[5767:155906] 6, 当前线程 : <NSThread: 0x6000016993c0>{number = 1, name = main}
2019-05-14 16:06:44.981833+0800 GCDDemo[5767:155906] 7, 当前线程 : <NSThread: 0x6000016993c0>{number = 1, name = main}
2019-05-14 16:06:44.981976+0800 GCDDemo[5767:155906] 8, 当前线程 : <NSThread: 0x6000016993c0>{number = 1, name = main}
2019-05-14 16:06:45.016921+0800 GCDDemo[5767:155906] 9, 当前线程 : <NSThread: 0x6000016993c0>{number = 1, name = main}
2019-05-14 16:06:45.017021+0800 GCDDemo[5767:155906] --- end ---
结果分析:同上
4、同步执行主队列
NSLog(@"--- begin ---");
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_sync(mainQueue, ^{
NSLog(@"1");
});
dispatch_sync(mainQueue, ^{
NSLog(@"2");
});
dispatch_sync(mainQueue, ^{
NSLog(@"3");
});
NSLog(@"--- end ---");
2019-05-14 15:19:00.807434+0800 GCDDemo[5154:130087] --- begin ---
(lldb)
崩溃截图.png
结果崩溃了
这边涉及到了线程死锁的概念, 简单说一下:这段代码本身(这里称做任务F,下同)就先添加再主队列里, NSLog(@"1"), NSLog(@"2"),NSLog(@"3")分别一次后添加到主队列里面, NSLog(@"1")这个任务在等待任务F执行完, 任务F要想执行完那必须等到NSLog(@"1"), NSLog(@"2"), NSLog(@"3")着三个任务都执行完了才能执行完, 这样就存在了任务F和NSLog(@"1")互相等待, 这就形成了主线程的死锁.(建议自己详细了解一下线程的死锁)
5、异步执行串行队列
NSLog(@"--- begin ---");
dispatch_queue_t serialQueue = dispatch_queue_create("com.example.gcd.serial", DISPATCH_QUEUE_SERIAL);
for (NSInteger i = 0; i < 10; i++) {
dispatch_async(serialQueue, ^{
NSLog(@"%ld, 当前线程 : %@", i, [NSThread currentThread]);
});
}
NSLog(@"--- end ---");
2019-05-14 16:08:38.492805+0800 GCDDemo[5793:157042] --- begin ---
2019-05-14 16:08:38.492977+0800 GCDDemo[5793:157042] --- end ---
2019-05-14 16:08:38.493042+0800 GCDDemo[5793:157082] 0, 当前线程 : <NSThread: 0x600001c69480>{number = 3, name = (null)}
2019-05-14 16:08:38.493195+0800 GCDDemo[5793:157082] 1, 当前线程 : <NSThread: 0x600001c69480>{number = 3, name = (null)}
2019-05-14 16:08:38.493331+0800 GCDDemo[5793:157082] 2, 当前线程 : <NSThread: 0x600001c69480>{number = 3, name = (null)}
2019-05-14 16:08:38.493441+0800 GCDDemo[5793:157082] 3, 当前线程 : <NSThread: 0x600001c69480>{number = 3, name = (null)}
2019-05-14 16:08:38.493559+0800 GCDDemo[5793:157082] 4, 当前线程 : <NSThread: 0x600001c69480>{number = 3, name = (null)}
2019-05-14 16:08:38.493667+0800 GCDDemo[5793:157082] 5, 当前线程 : <NSThread: 0x600001c69480>{number = 3, name = (null)}
2019-05-14 16:08:38.493780+0800 GCDDemo[5793:157082] 6, 当前线程 : <NSThread: 0x600001c69480>{number = 3, name = (null)}
2019-05-14 16:08:38.493911+0800 GCDDemo[5793:157082] 7, 当前线程 : <NSThread: 0x600001c69480>{number = 3, name = (null)}
2019-05-14 16:08:38.508214+0800 GCDDemo[5793:157082] 8, 当前线程 : <NSThread: 0x600001c69480>{number = 3, name = (null)}
2019-05-14 16:08:38.508361+0800 GCDDemo[5793:157082] 9, 当前线程 : <NSThread: 0x600001c69480>{number = 3, name = (null)}
结果分析: 先走的开始和结束, 任务依次执行, 开辟了新线程,只开辟了一条新线程
6、异步执行并行队列
NSLog(@"--- begin ---");
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.example.gcd.serial", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger i = 0; i < 10; i++) {
dispatch_async(concurrentQueue, ^{
NSLog(@"%ld, 当前线程 : %@", i, [NSThread currentThread]);
});
}
NSLog(@"--- end ---");
2019-05-14 16:14:01.097373+0800 GCDDemo[5837:159234] --- begin ---
2019-05-14 16:14:01.097566+0800 GCDDemo[5837:159234] --- end ---
2019-05-14 16:14:01.097710+0800 GCDDemo[5837:159276] 0, 当前线程 : <NSThread: 0x600003aa4200>{number = 3, name = (null)}
2019-05-14 16:14:01.097712+0800 GCDDemo[5837:159278] 3, 当前线程 : <NSThread: 0x600003a84a40>{number = 6, name = (null)}
2019-05-14 16:14:01.097710+0800 GCDDemo[5837:159275] 1, 当前线程 : <NSThread: 0x600003ae3f80>{number = 5, name = (null)}
2019-05-14 16:14:01.097783+0800 GCDDemo[5837:159283] 4, 当前线程 : <NSThread: 0x600003aab5c0>{number = 7, name = (null)}
2019-05-14 16:14:01.097783+0800 GCDDemo[5837:159277] 2, 当前线程 : <NSThread: 0x600003abfb00>{number = 4, name = (null)}
2019-05-14 16:14:01.097793+0800 GCDDemo[5837:159284] 5, 当前线程 : <NSThread: 0x600003aab580>{number = 8, name = (null)}
2019-05-14 16:14:01.097827+0800 GCDDemo[5837:159285] 6, 当前线程 : <NSThread: 0x600003abfb40>{number = 9, name = (null)}
2019-05-14 16:14:01.097882+0800 GCDDemo[5837:159286] 7, 当前线程 : <NSThread: 0x600003a84ac0>{number = 10, name = (null)}
2019-05-14 16:14:01.097895+0800 GCDDemo[5837:159275] 9, 当前线程 : <NSThread: 0x600003ae3f80>{number = 5, name = (null)}
2019-05-14 16:14:01.097909+0800 GCDDemo[5837:159278] 8, 当前线程 : <NSThread: 0x600003a84a40>{number = 6, name = (null)}
结果分析:顺序就是乱的了, 开辟了新线程, 开辟了不止一条新线程
7、异步执行全局队列
NSLog(@"--- begin ---");
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (NSInteger i = 0; i < 10; i++) {
dispatch_async(globalQueue, ^{
NSLog(@"%ld", i);
});
}
NSLog(@"--- end ---");
2019-05-14 15:59:03.987523+0800 GCDDemo[5675:151762] --- begin ---
2019-05-14 15:59:03.987725+0800 GCDDemo[5675:151762] --- end ---
2019-05-14 15:59:03.987863+0800 GCDDemo[5675:151803] 1, 当前线程 : <NSThread: 0x60000090c380>{number = 4, name = (null)}
2019-05-14 15:59:03.987862+0800 GCDDemo[5675:151806] 3, 当前线程 : <NSThread: 0x60000097f700>{number = 6, name = (null)}
2019-05-14 15:59:03.987865+0800 GCDDemo[5675:151804] 2, 当前线程 : <NSThread: 0x600000919b80>{number = 5, name = (null)}
2019-05-14 15:59:03.987887+0800 GCDDemo[5675:151805] 0, 当前线程 : <NSThread: 0x600000914080>{number = 3, name = (null)}
2019-05-14 15:59:03.987895+0800 GCDDemo[5675:151823] 4, 当前线程 : <NSThread: 0x60000094ed40>{number = 7, name = (null)}
2019-05-14 15:59:03.987928+0800 GCDDemo[5675:151824] 5, 当前线程 : <NSThread: 0x60000090c3c0>{number = 8, name = (null)}
2019-05-14 15:59:03.988011+0800 GCDDemo[5675:151825] 6, 当前线程 : <NSThread: 0x60000094eec0>{number = 9, name = (null)}
2019-05-14 15:59:03.988014+0800 GCDDemo[5675:151806] 8, 当前线程 : <NSThread: 0x60000097f700>{number = 6, name = (null)}
2019-05-14 15:59:03.988037+0800 GCDDemo[5675:151805] 9, 当前线程 : <NSThread: 0x600000914080>{number = 3, name = (null)}
2019-05-14 15:59:03.988040+0800 GCDDemo[5675:151826] 7, 当前线程 : <NSThread: 0x60000097f900>{number = 10, name = (null)}
结果分析:同上
8、异步执行主队列
NSLog(@"--- begin ---");
dispatch_queue_t mainQueue = dispatch_get_main_queue();
for (NSInteger i = 0; i < 10; i++) {
dispatch_async(mainQueue, ^{
NSLog(@"%ld, 当前线程 : %@", i, [NSThread currentThread]);
});
}
NSLog(@"--- end ---");
2019-05-14 15:56:57.099676+0800 GCDDemo[5648:150470] --- begin ---
2019-05-14 15:56:57.099889+0800 GCDDemo[5648:150470] --- end ---
2019-05-14 15:56:57.112562+0800 GCDDemo[5648:150470] 0, 当前线程 : <NSThread: 0x600001ce13c0>{number = 1, name = main}
2019-05-14 15:56:57.112749+0800 GCDDemo[5648:150470] 1, 当前线程 : <NSThread: 0x600001ce13c0>{number = 1, name = main}
2019-05-14 15:56:57.112850+0800 GCDDemo[5648:150470] 2, 当前线程 : <NSThread: 0x600001ce13c0>{number = 1, name = main}
2019-05-14 15:56:57.112945+0800 GCDDemo[5648:150470] 3, 当前线程 : <NSThread: 0x600001ce13c0>{number = 1, name = main}
2019-05-14 15:56:57.113067+0800 GCDDemo[5648:150470] 4, 当前线程 : <NSThread: 0x600001ce13c0>{number = 1, name = main}
2019-05-14 15:56:57.113166+0800 GCDDemo[5648:150470] 5, 当前线程 : <NSThread: 0x600001ce13c0>{number = 1, name = main}
2019-05-14 15:56:57.113297+0800 GCDDemo[5648:150470] 6, 当前线程 : <NSThread: 0x600001ce13c0>{number = 1, name = main}
2019-05-14 15:56:57.113417+0800 GCDDemo[5648:150470] 7, 当前线程 : <NSThread: 0x600001ce13c0>{number = 1, name = main}
2019-05-14 15:56:57.127392+0800 GCDDemo[5648:150470] 8, 当前线程 : <NSThread: 0x600001ce13c0>{number = 1, name = main}
2019-05-14 15:56:57.127536+0800 GCDDemo[5648:150470] 9, 当前线程 : <NSThread: 0x600001ce13c0>{number = 1, name = main}
结果分析:先执行的开始和结束, 中间的任务是按顺序执行的,没有开辟新线程
GCD之Group
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"%@",group);
NSLog(@"blok0");
});
dispatch_group_async(group, queue, ^{
NSLog(@"block1");
});
dispatch_group_async(group, queue, ^{
NSLog(@"block2");
});
dispatch_group_notify(group, queue, ^{
NSLog(@"done");
});
// dispatch_release(group); // 只有在MRC下才这么写,ARC下会自动管理
2019-05-14 16:24:25.308830+0800 GCDDemo[5922:163218] block1
2019-05-14 16:24:25.308830+0800 GCDDemo[5922:163217] block2
2019-05-14 16:24:25.308942+0800 GCDDemo[5922:163219] <OS_dispatch_group: 0x600003bc90e0>
2019-05-14 16:24:25.309028+0800 GCDDemo[5922:163219] blok0
2019-05-14 16:24:25.309138+0800 GCDDemo[5922:163219] done
结果分析: 最后才执行的dispatch_group_notify中的任务(应用场景:一个页面有多个数据请求,等所有的请求都回调回来后才刷新界面)
GCD之Barrier
dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.ForBarrier", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger i = 0; i < 5; i++) {
dispatch_async(queue, ^{
NSLog(@"%ld", i);
});
}
dispatch_barrier_async(queue, ^{
NSLog(@"--- ---");
});
for (NSInteger i = 5; i < 10; i++) {
dispatch_async(queue, ^{
NSLog(@"%ld", i);
});
}
2019-05-14 16:34:06.856068+0800 GCDDemo[6028:168004] 3
2019-05-14 16:34:06.856057+0800 GCDDemo[6028:168005] 1
2019-05-14 16:34:06.856057+0800 GCDDemo[6028:168003] 0
2019-05-14 16:34:06.856057+0800 GCDDemo[6028:168006] 2
2019-05-14 16:34:06.856151+0800 GCDDemo[6028:168010] 4
2019-05-14 16:34:06.856279+0800 GCDDemo[6028:168010] --- ---
2019-05-14 16:34:06.856373+0800 GCDDemo[6028:168010] 5
2019-05-14 16:34:06.856381+0800 GCDDemo[6028:168006] 6
2019-05-14 16:34:06.856389+0800 GCDDemo[6028:168003] 7
2019-05-14 16:34:06.856403+0800 GCDDemo[6028:168004] 8
2019-05-14 16:34:06.856422+0800 GCDDemo[6028:168011] 9
结果分析:barrier就是栏的意思, 就像一个挡板以它界限分割开了, 上面的任务异步执行, 下面的任务异步执行
GCD之Semaphore
// 使用信号量可以做到并行队列串行执行 ,而且当信号量为1时是按照代码顺序执行的
- (void)GCD_semaphore{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globalQueue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//当信号量>=1时,才会执行下面的代码,等待信号量-1
NSLog(@"first start");
NSLog(@"first end");
dispatch_semaphore_signal(semaphore);//信号量+1
});
dispatch_async(globalQueue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"second start");
NSLog(@"second end");
dispatch_semaphore_signal(semaphore);//信号量+1
});
dispatch_async(globalQueue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"third start");
NSLog(@"third end");
dispatch_semaphore_signal(semaphore);//信号量+1
});
}
2019-05-14 16:39:09.310763+0800 GCDDemo[6083:170514] first start
2019-05-14 16:39:09.310924+0800 GCDDemo[6083:170514] first end
2019-05-14 16:39:09.311018+0800 GCDDemo[6083:170512] second start
2019-05-14 16:39:09.311106+0800 GCDDemo[6083:170512] second end
2019-05-14 16:39:09.311184+0800 GCDDemo[6083:170513] third start
2019-05-14 16:39:09.311247+0800 GCDDemo[6083:170513] third end
结果分析: 按顺序依次执行 (这就是异步里面的同步)
semaphore个人使用总结:
dispatch_semaphore_wait 函数的作用:
1、如果dsema信号量的值大于0,该函数所处线程就继续执行下面的语句,
并且将信号量的值减1;
2、如果desema的值为0,那么这个函数就阻塞当前线程等待timeout(注意timeout的类型为dispatch_time_t,
需要传入对应的类型参数),如果等待的期间desema的值被dispatch_semaphore_signal函数加1了,且该函数(即dispatch_semaphore_wait)所处线程获得了信号量,那么就继续向下执行并将信号量减1。
3、如果等待期间没有获取到信号量或者信号量的值一直为0,那么等到timeout时,其所处线程自动执行其后语句。
转载请注明出处
原文链接: https://www.jianshu.com/p/8321f35e30b9
参考资料: https://www.jianshu.com/p/2d57c72016c6
补充:
GCD之定时器
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
/*
para1: 间隔几秒
para2: leeway (翻译:最小的余地)精确度
*/
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
//要执行的任务
NSLog(@"***");
});
//开始执行定时器
dispatch_resume(timer);
运行完之后你会发现没有日志输出
原因是我们创建的这个_timer在这段代码执行完后就被销毁了,可以看出GCD并没有管理它的内存,并没有强持有它,所以我们需要自己想办法让它不被销毁
@property (nonatomic, strong) dispatch_source_t timer;
- (void)GCD_timer {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
//GCD创建的timer必须被持有
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
/*
para1: 间隔几秒
para2: leeway (翻译:最小的余地)精确度
*/
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC);
dispatch_source_set_event_handler(self.timer, ^{
//要执行的任务
NSLog(@"***");
});
//开始执行定时器
dispatch_resume(self.timer);
}
2019-05-14 20:01:49.960536+0800 GCDDemo[8032:248654] ***
2019-05-14 20:01:50.995122+0800 GCDDemo[8032:248654] ***
2019-05-14 20:01:52.048355+0800 GCDDemo[8032:248653] ***
2019-05-14 20:01:52.960705+0800 GCDDemo[8032:248654] ***
2019-05-14 20:01:53.960540+0800 GCDDemo[8032:248654] ***
2019-05-14 20:01:55.051170+0800 GCDDemo[8032:248654] ***
2019-05-14 20:01:56.058094+0800 GCDDemo[8032:248666] ***
网友评论