iOS多线程GCD
2015-12-25 15:37
225 查看
GCD(Grand Central Dispatch) : 牛逼的中枢调度器。苹果自带,纯C语言实现,提供了非常多且强大的函数,它可以提高代码的执行效率与多核的利用率。
一、GCD的基本使用
1、GCD中的两个核心概念:
•任务: 执行什么任务.
•队列: 用来存放任务. (用来调度任务)
2、GCD使用的2个步骤:
•1.定制任务. (确定想做的事情)
•2.将任务添加到队列中.
•GCD会自动将队列中的任务取出, 放到对应的线程中执行.
•遵循队列的FIFO原则: 先进先出.
3、同步和异步的区别: (是否开启新线程)
•同步:在当前线程中执行.
•异步:在另一条线程中执行.
4、并行与串行队列 :
(任务的执行方式)
•并行对列:在异步情况下, 让多个任务并发执行.
•串行队列:一个任务执行完后,再执行下一个任务.
队列又分为几种:自定义的队列、全局队列、主队列
基本使用代码如下:
[objc] view
plaincopy
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self gcdDemo4];
}
#pragma mark - 串行队列
- (void)gcdDemo1{
// 1. 串行队列
// 在使用GCD的时候,先敲dispatch
// 在C语言中,定义对象通常是以 _t 或者 Ref 结尾的
dispatch_queue_t q = dispatch_queue_create("myQueueName", DISPATCH_QUEUE_SERIAL); //DISPATCH_QUEUE_SERIAL 的值为 NULL
NSLog(@"%@", [NSThread currentThread]);
// 2. 同步任务 sync(实际开发中没用)
for (int i = 0; i < 10; i++) {
dispatch_sync(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
// 2. 异步任务 async,能够开线程
// 串行队列中,异步任务最多只能开一条线程,所有任务顺序执行!
// 串行队列,异步任务,在多线程中,是斯坦福大学最推荐的一种多线程方式!
// 优点:将任务放在其他线程中工作,每个任务顺序执行,便于调试
// 缺点:并发能力不强,最多只能使用一条线程!
for (int i = 0; i < 10; i++) {
dispatch_async(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
}
#pragma mark - 并行队列
- (void)gcdDemo2{
// 1. 并行队列
dispatch_queue_t q = dispatch_queue_create("myQueueName", DISPATCH_QUEUE_CONCURRENT);
// 非ARC中,需要自己释放队列
// dispatch_release(q);
// 2. 同步任务,不会开启新的线程
// 在实际开发中,同步任务可以保证执行完成之后,才让后续的异步任务开始执行,用于控制任务之间的先后顺序,如在后台线程中,处理“用户登录”等
for (int i = 0; i < 10; i++) {
dispatch_sync(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
// 3. 异步任务,会在多条线程上工作,具体开多少条线程,由系统决定
// 仍然是按照任务添加到队列中的顺序被调度,只是执行先后可能会有差异!
// *** 能够将耗时的操作,放到子线程中工作
// *** 与串行队列异步任务相比,并发性能更好!但是执行的先后顺序,不固定
for (int i = 0; i < 10; i++) {
dispatch_async(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
}
#pragma mark - 全局并行(并发)队列(使用更为普遍一些)
- (void)gcdDemo3{
// 1. 获取全局队列(与自定义并行队列的区别就是名字显示,其他都一样)
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 使用全局队列,不需要考虑共享的问题
// 2. 同步任务
for (int i = 0; i < 10; i++) {
dispatch_sync(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
// 3. 异步任务
for (int i = 0; i < 10; i++) {
dispatch_async(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
}
#pragma mark - 主队列(专门调度在主线程上工作的队列,不能开线程)
- (void)gcdDemo4{
// 1. 获取主队列
dispatch_queue_t q = dispatch_get_main_queue();
// 2. 不要同步任务(死锁!!!)
// dispatch_sync(q, ^{
// NSLog(@"不会输出的!!!");
// });
// 3. 异步任务,在主线程上依次顺序执行
for (int i = 0; i < 10; i++) {
dispatch_async(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
}
二、GCD进行线程间通讯
这里从主线程调用下载图片的方法,开启一个线程下载,然后在该线程任务完成后,返回主线程。
[objc] view
plaincopy
- (void)downloadImage{
// 1. 全局并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 2. 异步任务
dispatch_async(queue, ^{
NSLog(@"开始下载图片 %@", [NSThread currentThread]);
//。。。。
NSLog(@"完成下载图片 %@", [NSThread currentThread]);
// 3. 通知主队列更新UI
// 给主队列,添加一个异步任务,更新UI
dispatch_async(dispatch_get_main_queue(), ^{
//可以做更新UI操作。。。。
});
});
}
下面的2篇不错,可以更好的理解:
http://blog.csdn.net/onlyou930/article/details/8225906 http://www.cnblogs.com/pure/archive/2013/03/31/2977420.html
转载请注明出处:http://blog.csdn.net/xn4545945
一、GCD的基本使用
1、GCD中的两个核心概念:
•任务: 执行什么任务.
•队列: 用来存放任务. (用来调度任务)
2、GCD使用的2个步骤:
•1.定制任务. (确定想做的事情)
•2.将任务添加到队列中.
•GCD会自动将队列中的任务取出, 放到对应的线程中执行.
•遵循队列的FIFO原则: 先进先出.
3、同步和异步的区别: (是否开启新线程)
•同步:在当前线程中执行.
•异步:在另一条线程中执行.
4、并行与串行队列 :
(任务的执行方式)
•并行对列:在异步情况下, 让多个任务并发执行.
•串行队列:一个任务执行完后,再执行下一个任务.
队列又分为几种:自定义的队列、全局队列、主队列
基本使用代码如下:
[objc] view
plaincopy
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self gcdDemo4];
}
#pragma mark - 串行队列
- (void)gcdDemo1{
// 1. 串行队列
// 在使用GCD的时候,先敲dispatch
// 在C语言中,定义对象通常是以 _t 或者 Ref 结尾的
dispatch_queue_t q = dispatch_queue_create("myQueueName", DISPATCH_QUEUE_SERIAL); //DISPATCH_QUEUE_SERIAL 的值为 NULL
NSLog(@"%@", [NSThread currentThread]);
// 2. 同步任务 sync(实际开发中没用)
for (int i = 0; i < 10; i++) {
dispatch_sync(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
// 2. 异步任务 async,能够开线程
// 串行队列中,异步任务最多只能开一条线程,所有任务顺序执行!
// 串行队列,异步任务,在多线程中,是斯坦福大学最推荐的一种多线程方式!
// 优点:将任务放在其他线程中工作,每个任务顺序执行,便于调试
// 缺点:并发能力不强,最多只能使用一条线程!
for (int i = 0; i < 10; i++) {
dispatch_async(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
}
#pragma mark - 并行队列
- (void)gcdDemo2{
// 1. 并行队列
dispatch_queue_t q = dispatch_queue_create("myQueueName", DISPATCH_QUEUE_CONCURRENT);
// 非ARC中,需要自己释放队列
// dispatch_release(q);
// 2. 同步任务,不会开启新的线程
// 在实际开发中,同步任务可以保证执行完成之后,才让后续的异步任务开始执行,用于控制任务之间的先后顺序,如在后台线程中,处理“用户登录”等
for (int i = 0; i < 10; i++) {
dispatch_sync(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
// 3. 异步任务,会在多条线程上工作,具体开多少条线程,由系统决定
// 仍然是按照任务添加到队列中的顺序被调度,只是执行先后可能会有差异!
// *** 能够将耗时的操作,放到子线程中工作
// *** 与串行队列异步任务相比,并发性能更好!但是执行的先后顺序,不固定
for (int i = 0; i < 10; i++) {
dispatch_async(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
}
#pragma mark - 全局并行(并发)队列(使用更为普遍一些)
- (void)gcdDemo3{
// 1. 获取全局队列(与自定义并行队列的区别就是名字显示,其他都一样)
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 使用全局队列,不需要考虑共享的问题
// 2. 同步任务
for (int i = 0; i < 10; i++) {
dispatch_sync(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
// 3. 异步任务
for (int i = 0; i < 10; i++) {
dispatch_async(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
}
#pragma mark - 主队列(专门调度在主线程上工作的队列,不能开线程)
- (void)gcdDemo4{
// 1. 获取主队列
dispatch_queue_t q = dispatch_get_main_queue();
// 2. 不要同步任务(死锁!!!)
// dispatch_sync(q, ^{
// NSLog(@"不会输出的!!!");
// });
// 3. 异步任务,在主线程上依次顺序执行
for (int i = 0; i < 10; i++) {
dispatch_async(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
}
二、GCD进行线程间通讯
这里从主线程调用下载图片的方法,开启一个线程下载,然后在该线程任务完成后,返回主线程。
[objc] view
plaincopy
- (void)downloadImage{
// 1. 全局并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 2. 异步任务
dispatch_async(queue, ^{
NSLog(@"开始下载图片 %@", [NSThread currentThread]);
//。。。。
NSLog(@"完成下载图片 %@", [NSThread currentThread]);
// 3. 通知主队列更新UI
// 给主队列,添加一个异步任务,更新UI
dispatch_async(dispatch_get_main_queue(), ^{
//可以做更新UI操作。。。。
});
});
}
下面的2篇不错,可以更好的理解:
http://blog.csdn.net/onlyou930/article/details/8225906 http://www.cnblogs.com/pure/archive/2013/03/31/2977420.html
转载请注明出处:http://blog.csdn.net/xn4545945
相关文章推荐
- [置顶] iOS 中 Storyboard 与 Xib 间控制器跳转 - 简化整理完整版
- iOS请求数据AFNetworking
- iOS 实现多个按钮,点选一个其它都取消选中状态的最佳方法
- iOS文件下载
- iOS文件上传
- iOS代理、block传值
- iOS Quartz2D简单的使用
- WWDC 2014 Session笔记 - iOS界面开发的大一统
- IOS开发 3DTouch
- iOS 设置导航栏之二(设置导航栏的颜色、文字的颜色、左边按钮的文字及颜色)
- iOS Quartz 2D绘图用CGContextRef绘制三角形 —— HERO博客
- 我的第一次份实习工作-iOS实习生-第二个月
- iOS Kernel Exploitation Training (April 2015)
- iOS给label添加下划线
- IOS 中关于自定义Cell 上的按钮 开关等点击事件的实现方法(代理)
- ios编程之Core Data(一)
- iOS开发~CocoaPods使用详细说明
- IOS学习笔记之KVC、KVO
- 我的第一次份实习工作-iOS实习生-第一个月
- IOS Block 反向传值