1、NSObject的多线程方法——后台线程
2、NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程)
以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题
3、NSOperation/NSOperationQueue 面向对象的线程技术
4、GCD —— Grand Central Dispatch(派发) 是基于C语言的框架,可以充分利用多核,是苹果推荐使用的多线程技术
以上这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。但是就目前而言,iOS的开发者,需要了解三种多线程技术的基本使用过程。因为很多框架技术分别使用了不同多线程技术。
NSThread:
优点:NSThread 比其他两个轻量级,使用简单
缺点:需要自己管理线程的生命周期、线程同步、加锁、睡眠以及唤醒等。线程同步对数据的加锁会有一定的系统开销
NSOperation:
不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上
NSOperation是面向对象的
GCD:
Grand Central Dispatch是由苹果开发的一个多核编程的解决方案。iOS4.0+才能使用,是替代NSThread, NSOperation的高效和强大的技术
GCD是基于C语言的
NSObject
//在后台执行(最简单)
[self performSelectorInBackground:@selector(test) withObject:nil];
NSThread
//NSThread是一个轻量级的多线程,有以下两种方式创建。
//1.初始化并手动开启子线程
// NSThread *thread =[[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil];
// //开启子线程
// [thread start];
// //取消子线程
// [thread cancel];
//2.初始化的同时开启子线程
[NSThread detachNewThreadSelector:@selector(test) toTarget:self withObject:nil];
NSOperation
//NSOperaction在MVC里面属于M层,用来封装单个任务的数据和相关代码的抽象类,我们一般使用他的子类NSInvocationOperation和NSBlockOperation
//NSOperation本身并无主线程,子线程之分,只是一个操作,通常与NSOperationQueue结合使用
NSInvocationOperation *invoOperaction = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
__weak typeof(self)temp = self;
// __weak ViewController *temp1 = self;
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
[temp test];
NSLog(@"这是BLOCK执行的");
}];
//nsoperationQueue是线程操作列队,用来管理一组NSOperationQueue,会根据需求创建出适合数量的子线程,完成任务的并发执行
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:invoOperaction];
[queue addOperation:blockOperation];
//设置最大并发执行数,当数量为1的时候,线程编程同步执行(串行)
[queue setMaxConcurrentOperationCount:2];
GCD
//GCD有三种列队
/*
1,主列队(串行)
2,全局列队(并行)
3,自定义列队(串行列队,并行列队)
*/
//,主列队
//获取主列队(生成了一个串行的队列,队列里面的block按照FIFO(先进后出)的顺序执行,实际上为单线程队列)
dispatch_queue_t mainQueue = dispatch_get_main_queue();
__weak typeof(self)temp = self;
/*
//向列队添加任务
dispatch_async(mainQueue, ^{
[temp test];
NSLog(@"1:%@--%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
// dispatch_async(mainQueue, ^{
// [temp test];
// NSLog(@"2:%@--%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
// });
//定义时间
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"无语");
});
*/
//全局列队(并行)
dispatch_queue_t global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(global, ^{
[temp test];
NSLog(@"1:%@--%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(global, ^{
[temp test];
NSLog(@"2:%@--%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), global, ^{
NSLog(@"4秒");
});
//指定次数,将指定的block加入到指定的队列里面,并等待全部执行完毕。
//1参数:指定重复次数
//2.参数:指定队列
//3.参数:
dispatch_apply(5, global, ^(size_t t) {
NSLog(@"执行次数:%zu",t);
});
//主队列只能串行执行,全局队列只能并行执行,且他们都是单列
//自定义队列
//1.参数:队列的名称
//2.参数:指定队列列行
dispatch_queue_t queue1 = dispatch_queue_create("AAA", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue1, ^{
NSLog(@"我是第一个");
[temp test];
});
dispatch_async(queue1, ^{
NSLog(@"我是第二个");
[temp test];
});
//添加函数
dispatch_async_f(queue1, "context", function);
//添加延时block
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), queue1, ^{
NSLog(@"等的都快发霉了。");
});
//添加重复
dispatch_apply(5, queue1, ^(size_t t) {
//输入想重复操作的代码
NSLog(@"a");
});