05-10
0
iOS 多线程
一、iOS中常见的多线程方案
1、pthread
- 一套通用的多线程API
- 适用于Unix\Linux\Windows等系统
- 跨平台、可移植
- 使用难度大
- 使用C语言
- 程序员管理线程生命周期
- 实际项目中几乎不用
2、NSThread
- 使用更加面向对象
- 简单易用、可直接操作线程对象
- 使用OC语言
- 程序员管理线程生命周期
- 实际项目中几乎不用
3、GCD
- 旨在替代NSThread技术
- 充分利用设备的多核
- 使用C语言
- 自动管理线程生命周期
- 实际项目中经常使用
4、NSOperation
- 基于GCD(底层是GCD)
- 比GCD多了一些简单实用的功能
- 使用更加面向对象
- 使用OC语言
- 自动管理线程生命周期
- 实际项目中经常使用
二、GCD
1、GCD有两个用来执行任务的函数
- 同步(sync):只能在当前线程中执行任务,不具备开启新线程的能力,任务立刻马上执行,会阻塞当前线程并等待 Block中的任务执行完毕dispatch函数才会返回,然后当前线程才会继续往下运行。
- 异步(async):可以在新的线程中执行任务,具备开启线程的能力,但不一定会开启新的线程,dispatch函数会立即返回, 然后Block在后台异步执行,即当前线程会直接往下执行,不会阻塞当前线程。
#pragma mark - 同步执行
- (void)syncQueue {
NSLog(@"同步主线程开始");
//创建串行队列
dispatch_queue_t queue = dispatch_queue_create("com.weixin.globalQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"同步线程");
});
NSLog(@"同步主线程结束");
}
#pragma mark - 异步执行
- (void)asyncQueue {
NSLog(@"异步主线程开始");
dispatch_queue_t queue = dispatch_queue_create("com.qq.globalQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"异步线程");
});
NSLog(@"异步主线程结束");
}
2、队列
用于存放任务,分为串行队列和并行队列。
- 串行队列:所有任务会在一条线程中执行(有可能是当前线程也有可能是新开辟的线程),并且一个任务执行完毕后,才开始执行下一个任务。
- 并行队列:可以开启多条线程并行执行任务(但不一定会开启新的线程),并且当一个任务放到指定线程开始执行时,下一个任务就可以开始执行了
- 创建队列:
1.串行队列
//创建串行队列
dispatch_queue_t firstQueue = dispatch_queue_create("com.weibo", DISPATCH_QUEUE_SERIAL);
2.并行队列
//创建并行队列
dispatch_queue_t secondQueue = dispatch_queue_create("com.facebook", DISPATCH_QUEUE_CONCURRENT);
3.创建全局默认并发队列
//创建全局默认并发队列
/**
第一个参数:优先级 也可直接填后面的数字
#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台
第二个参数: 预留参数 0
*/
dispatch_queue_t queue3 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
4.获取主队列
//获取主队列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
5.队列组
dispatch_group_async & dispatch_group_notify
#pragma mark - 队列组
- (void)GCDGroup {
//创建队列组
dispatch_group_t group = dispatch_group_create();
//1.开子线程下载图片
//创建队列(并发)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//下载图片1
dispatch_group_async(group, queue, ^{
NSURL *url = [NSURL URLWithString:@"http://www.huabian.com/uploadfile/2015/0914/20150914014032274.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
self.image1 = [UIImage imageWithData:data];
NSLog(@"image1 ==== %@",self.image1);
});
//下载图片2
dispatch_group_async(group, queue, ^{
NSURL *url = [NSURL URLWithString:@"http://img1.3lian.com/img2011/w12/1202/19/d/88.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
self.image2 = [UIImage imageWithData:data];
NSLog(@"image2 ==== %@",self.image2);
});
//group中所有任务执行完毕,通知该方法执行
dispatch_group_notify(group, queue, ^{
//开启图形上下文
UIGraphicsBeginImageContext(CGSizeMake(200, 200));
//画1
[self.image1 drawInRect:CGRectMake(0, 0, 200, 100)];
//画2
[self.image2 drawInRect:CGRectMake(0, 100, 200, 100)];
//根据图形上下文拿到图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
//关闭上下文
UIGraphicsEndImageContext();
//回到主线程刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = image;
NSLog(@"%@--刷新UI",[NSThread currentThread]);
});
});
}