iOS多线程GCD详解

 

咱们在这里复习下GCD。git

1.什么是GCD?

GCD全称Grand Central Dispatch,咱们通俗的翻译叫牛逼的中心调度。github

2.咱们用GCD干什么?

经过 GCD,开发者不用再直接跟线程打交道了,只须要向队列中添加代码块便可,GCD 在后端管理着一个线程池。GCD 不只决定着你的代码块将在哪一个线程被执行,它还根据可用的系统资源对这些线程进行管理。这样能够将开发者从线程管理的工做中解放出来,经过集中的管理线程,来缓解大量线程被建立的问题。后端

GCD 带来的另外一个重要改变是,做为开发者能够将工做考虑为一个队列,而不是一堆线程,这种并行的抽象模型更容易掌握和使用。多线程

首先,系统提供给你一个叫作 主队列(main queue) 的特殊队列。和其它串行队列同样,这个队列中的任务一次只能执行一个。然而,它能保证全部的任务都在主线程执行,而主线程是惟一可用于更新 UI 的线程。这个队列就是用于发生消息给 UIView 或发送通知的。并发

系统同时提供给你好几个并发队列。它们叫作 全局调度队列(Global Dispatch Queues) 。目前的四个全局队列有着不一样的优先级:background、low、default 以及 high。要知道,Apple 的 API 也会使用这些队列,因此你添加的任何任务都不会是这些队列中惟一的任务。app

最后,你也能够建立本身的串行队列或并发队列。这就是说,至少有五个队列任你处置:主队列、四个全局调度队列,再加上任何你本身建立的队列。异步

3.GCD相比其余多线程有哪些优势?

  • GCD 能经过推迟昂贵计算任务并在后台运行它们来改善你的应用的响应性能。
  • GCD 提供一个易于使用的并发模型而不单单只是锁和线程,以帮助咱们避开并发陷阱。
  • GCD 具备在常见模式(例如单例)上用更高性能的原语优化你的代码的潜在能力。
  • GCD 会自动利用更多的CPU内核(好比双核、四核)

4.GCD术语

  • 串行(Serial):让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
  • 并发(Concurrent):可让多个任务并发(同时)执行(自动开启多个线程同时执行任务)并发功能只有在异步(dispatch_async)函数下才有效。
  • 同步(Synchronous):在当前线程中执行任务,不具有开启新线程的能力
  • 异步(Asynchronous):在新的线程中执行任务,具有开启新线程的能力

5.使用GCD

1.认识主队列,感觉串行队列的运行,运行结果打印的是 1,2,3,4,顺序执行。async

1
2
3
4
5
6
7
8
9
10
11
12
13
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
NSLog(@"1");
});
dispatch_async(mainQueue, ^{
NSLog(@"2");
});
dispatch_async(mainQueue, ^{
NSLog(@"3");
});
dispatch_async(mainQueue, ^{
NSLog(@"4");
});

2.认识全局队列,体验并发队列的运行,运行结果随机打印:2,3,1,4,随机执行。函数

1
2
3
4
5
6
7
8
9
10
11
12
13
dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(defaultQueue, ^{
NSLog(@"1");
});
dispatch_async(defaultQueue, ^{
NSLog(@"2");
});
dispatch_async(defaultQueue, ^{
NSLog(@"3");
});
dispatch_async(defaultQueue, ^{
NSLog(@"4");
});

3.建立自定义队列性能

1
2
3
4
5
6
7
8
9
10
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.bjsxt.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(concurrentQueue, ^{
NSLog(@"4");
dispatch_sync(concurrentQueue, ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"5");
});
NSLog(@"6");
});

4.GCD在单例中的运用dispatch_once

1
2
3
4
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"onceToken");
});

5.延迟加载dispatch_after

1
2
3
4
5
6
double delayInSeconds = 2.0;
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW,delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, mainQueue, ^{
NSLog(@"延时执行的2秒");
});

6.调度组dispatch_group_t

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, defaultQueue, ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"1");
});
dispatch_group_async(group, defaultQueue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"2");
});
dispatch_group_notify(group, defaultQueue, ^{
NSLog(@"3");
});

//等价于

// dispatch_group_enter(group);
// dispatch_async(defaultQueue, ^{
//
// NSLog(@"1");
// dispatch_group_leave(group);
// });

7.dispatch_barrier_async

在前面的任务执行结束后它才执行,并且它后面的任务等它执行完成以后才会执行.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
dispatch_queue_t queue = dispatch_queue_create("com.bjsxt.barrierExecute", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"1");
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:4];
NSLog(@"2");
});
dispatch_barrier_async(queue, ^{
NSLog(@"3");
[NSThread sleepForTimeInterval:4];

});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"4");
});

8.执行某个代码dispatch_apply

1
2
3
4
dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(5, defaultQueue, ^(size_t i) {
NSLog(@"%lu",i);
});

参考文章:

https://github.com/nixzhu/dev-blog

http://objccn.io/issue-2-1/

另外.....

个人愿望是.......

世界和平.........

相关文章
相关标签/搜索