多线程
1.基本概念
线程:程序执行流的最小单元,线程是进程中的一个实体。
进程: 一个具有一定独立功能的程序关于某个数据集合的一次运行活动。可以理解成一个运行中的应用程序。
同步: 只能在当前线程按先后顺序依次执行,不开启新线程。
异步: 可以在当前线程开启多个新线程执行,可不按顺序执行。
队列: 装载线程任务的队形结构。
并发: 线程执行可以同时一起进行执行。
串行: 线程执行只能依次逐一先后有序的执行。
NSThread
每个NSThread对象对应一个线程,真正最原始的线程。
1)优点:NSThread 轻量级最低,相对简单。
2)缺点:手动管理所有的线程活动,如生命周期、线程同步、睡眠等。
三种实现开启线程方式:
1.动态实例化
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadImageSource:) object:imgUrl];
thread.threadPriority = 1; //设置线程的优先级(0.0 - 1.0,1.0最高级)
[thread start];
2.静态实例化
[NSThread detachNewThreadSelector:@selector(loadImageSource:) toTarget:self withObject:imgUrl];
3.隐式实例化
[self performSelectorInBackground:@selector(loadImageSource:) withObject:imgUrl];
4.NSThread 的其他方法
//获取当前线程
NSThread *current = [NSThread currentThread];
//获取主线程
NSThread *main = [NSThread mainThread];
//暂停当前线程
[NSThread sleepForTimeInterval:2];
//线程之间通信
//在指定线程上执行操作
[self performSelector:@selector(run) onThread:thread withObject:nil waitUntilDone:YES];
//在主线程上执行操作
[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES];
//在当前线程执行操作
[self performSelector:@selector(run) withObject:nil];
GCD
它是苹果为多核的并行运算提出的解决方案,所以会自动合理地利用更多的CPU内核(比如双核、四核),最重要的是它会自动管理线程的生命周期,使用起来也更加灵活方便。
在 GCD 中加入了两个概念:任务和队列
1.创建UI主线程队列,用于刷新 UI
dispatch_queue_t queue = dispatch_get_main_queue();
2.创建串行队列
dispatch_queue_t queue = dispatch_queue_create("minggo.app.com", NULL);
3.创建并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
第一个参数用于指定优先级,分别使用 DISPATCH_QUEUE_PRIORITY_HIGH 和 DISPATCH_QUEUE_PRIORITY_LOW 两个常量来获取优先级。
4.多线程的实现
//后台执行线程创建
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self loadImageSource:imgUrl1];
});
//UI线程执行(只是为了测试,长时间加载内容不放在主线程)
dispatch_async(dispatch_get_main_queue(), ^{
[self loadImageSource:imgUrl1];
});
//一次性执行(常用来写单例)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self loadImageSource:imgUrl1];
});
//并发地执行循环迭代
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
size_t count = 10;
dispatch_apply(count, queue, ^(size_t i) {
NSLog(@"循环执行第%li次",i);
[self loadImageSource:imgUrl1];
});
//延迟执行
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self loadImageSource:imgUrl1];
});
//自定义
dispatch_queue_t urls_queue = dispatch_queue_create("minggo.app.com", NULL);
dispatch_async(urls_queue, ^{
[self loadImageSource:imgUrl1];
});
NSOperation
NSOperation是苹果公司对 GCD 的封装,完全面向对象。并且,自带线程管理。
主要的实现方式:实例化NSOperation的子类,绑定执行的操作。创建NSOperationQueue队列,将NSOperation实例添加进来。系统会自动将NSOperationQueue队列中检测取出和执行NSOperation的操作。
NSOperation 只是一个抽象类,所以不能封装任务,但它有 2 个子类用于封装任务,分别是:NSInvocationOperation 和 NSBlockOperation。
1.NSInvocationOperation 创建线程。
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadImageSource:) object:imgUrl];
//[invocationOperation start];//直接会在当前线程主线程执行
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:invocationOperation];
2.NSBlockOperation 创建线程
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
[self loadImageSource:imgUrl];
}];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:blockOperation];
3.自定义 NSOperation 子类实现 main 方法
//main方法实现
-(void)main {
// Do somthing
}
//创建线程实例并添加到队列中
LoadImageOperation *imageOperation = [LoadImageOperation new];
imageOperation.loadDelegate = self;
imageOperation.imgUrl = imgUrl;
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:imageOperation];