GCD实践——串行队列/并发队列与iOS多线程详解
来源:互联网 发布:城觅倒闭 知乎 编辑:程序博客网 时间:2024/06/15 14:36
GCD(Grand Central Dispatch),是苹果提供的一个解决多线程开发的解决方案。GCD会自动管理线程的生命周期(创建线程,调度任务,销毁线程),完全不需要我们管理,我们只需要告诉干什么就行。同时GCD使用block来进行任务的执行,用起来非常方便、灵活。本篇博客我们主要将GCD,其他的多线程实现方式还有NSThread、NSOperationQueue,我们将会在以后的博客中讲解。
这里我们要提到一个概念:【任务】。就是操作,就是你要执行的一段代码,在GCD中就是一个Block,所以添加任务十分方便。
【同步执行】:只要是同步执行的任务,都会在当前线程执行,不会另开线程。所以说网络请求等耗时操作一般不使用同步,而是异步,否则会阻塞主线程,界面会卡住。
【异步执行】:只要是异步任务执行的任务,都会另开线程,在别的线程执行。
同步(sync)和异步(async)的主要区别在于会不会阻塞当前线程,直到Block中的任务执行完毕。
如果是同步(sync)操作,它会阻塞当前线程并等待Block中的任务执行完毕,然后当前线程才会继续往下运行(因为同步操作没有开新线程,是在主线程中执行的,所以会阻塞)。
如果是异步(async)操作,当前线程会直接往下执行,他不会阻塞当前线程(因为异步操作是在另一个线程中执行的,所以不会阻塞主线程)。
队列:用于存放任务,一共有两种队列:串行队列和并行队列。
1.串行队列(private dispatch queue)一次只执行一个线程,按照添加到队列的顺序依次执行;
2.并行队列(global dispatch queue)一次可以执行多个线程,线程的执行没有先后顺序。根据同步或者异步有不同的执行方式。放到并行队列的任务,GCD也会FIFO的取出来,但不同的是,他取出来一个就会放到别的线程,然后再取出来一个又放到另一个线程。
3.Main dispatch queue:UI界面所在的线程队列是主线程。
下面我对上述几个案例进行代码示例:项目已经上传至github: https://github.com/chenyufeng1991/GCD 。中的GCD1项目。
【串行队列示例】
(1)首先导入GCD封装后的代码,可以从我的项目中直接复制,总共9个文件:其实个人推荐使用iOS原生的GCD,请移步《iOS开发——GCD的使用与多线程开发浅析》这篇博客。
。
(2)ViewController中的实现如下:
#import "ViewController.h"#import "GCD.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //执行串行队列; [self serailQueue]; }//串行队列;- (void)serailQueue{ //创建出队列; GCDQueue *queue = [[GCDQueue alloc] initSerial]; //执行队列中的线程; [queue execute:^{ NSLog(@"1"); }]; [queue execute:^{ NSLog(@"2"); }]; [queue execute:^{ NSLog(@"3"); }]; [queue execute:^{ NSLog(@"4"); }]; [queue execute:^{ NSLog(@"5"); }]; }@end
(3)执行结果如下:
。
(4)结果分析
输出结果和我们的预期一样,是按照添加到队列的顺序执行的。
【并行队列示例】
(1)同样需要引入GCD源代码,在ViewController中的实现如下:
#import "ViewController.h"#import "GCD.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //执行并发队列; [self concurrent]; }//并发队列;- (void)concurrent{ //创建出队列; GCDQueue *queue = [[GCDQueue alloc] initConcurrent]; //执行队列中的线程; [queue execute:^{ NSLog(@"1"); }]; [queue execute:^{ NSLog(@"2"); }]; [queue execute:^{ NSLog(@"3"); }]; [queue execute:^{ NSLog(@"4"); }]; [queue execute:^{ NSLog(@"5"); }]; }@end
(2)结果输出:
。
(3)结果分析:
输出结果和我们预期的一样,执行的顺序是无序的。
【UI界面更新】
(1)使用GCD,我们可以来进行网络操作或者下载请求,然后更新UI。这一系列操作是串行操作,需要有一定的顺序。在这里我使用了同步请求。在ViewController中实现如下:
#import "ViewController.h"#import "GCD.h"@interface ViewController ()@property(strong,nonatomic) UIImage *image;@property (weak, nonatomic) IBOutlet UIImageView *imageView;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //globalqueue其实就是并行队列。 [GCDQueue executeInGlobalQueue:^{ //处理业务逻辑 NSString *url = @"http://imgsrc.baidu.com/forum/w%3D580/sign=2e824145d2c8a786be2a4a065708c9c7/5a8e72094b36acaf254077437fd98d1000e99c4a.jpg"; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]]; NSData *picData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSLog(@"处理业务逻辑"); //获取图片; self.image = [UIImage imageWithData:picData]; [GCDQueue executeInMainQueue:^{ NSLog(@"更新UI"); //更新UI [self.imageView setImage:self.image]; }]; }]; }@end
(2)注意,我在storyboard中放了一个ImageView控件。运行效果如下:
。
github主页:https://github.com/chenyufeng1991 。欢迎大家访问!
- GCD实践——串行队列/并发队列与iOS多线程详解
- ios多线程操作(五)—— GCD串行队列与并发队列
- ios多线程操作(五)—— GCD串行队列与并发队列
- iOS-多线程编程学习之GCD——串行队列和并发队列(五)
- GCD之串行队列与并发队列
- iOS详解 GCD 串行队列并行队列
- 多线程——GCD(串行队列)
- GCD 多线程——串行队列
- 多线程——GCD(串行队列)
- GCD编程-串行队列与并发队列
- GCD串行并发队列扫盲
- GCD串行并发队列扫盲
- GCD串行并发队列扫盲
- GCD串行并发队列扫盲
- GCD串行并发队列扫盲
- iOS 之GCD串行和并发队列的理解
- iOS 之GCD串行和并发队列的理解
- 多线程GCD的详细讲解 任务和队列(串行队列,并发队列) (一)
- Android加载图片时出现OOM(OutOfMermary)的问题解决方案
- 扩展和压缩制表符
- logging
- 硬件 - CPU2
- 简单的数据库链式操作的例子
- GCD实践——串行队列/并发队列与iOS多线程详解
- R语言-简单回归分析
- 深入了解MFC中的文挡/视结构
- ios显示gif格式图片
- 自定义换行容器
- 重新认识Java线程的概念
- Lucene.Net+盘古分词器(详细介绍)
- EasyUI常用总结
- 用photoshop+perfecticon工具制作icon程序图标