一、NSObject的多线程方法——后台线程程序员
二、NSThread 每一个NSThread对象对应一个线程,量级较轻(真正的多线程)
如下两点是苹果专门开发的“并发”技术,使得程序员能够再也不去关心线程的具体使用问题
三、NSOperation/NSOperationQueue 面向对象的线程技术
四、GCD —— Grand Central Dispatch(派发) 是基于C语言的框架,能够充分利用多核,是苹果推荐使用的多线程技术编程
NSThread:
优势:NSThread 比其余两个轻量级,使用简单
缺点:须要本身管理线程的生命周期、线程同步、加锁、睡眠以及唤醒等。线程同步对数据的加锁会有必定的系统开销
多线程
NSOperation:
不须要关心线程管理,数据同步的事情,能够把精力放在本身须要执行的操做上
NSOperation是面向对象的
并发
工做原理:
用NSOperation封装要执行的操做
将建立好的NSOperation对象放NSOperationQueue中
启动OperationQueue开始新的线程执行队列中的操做
注意事项:
使用多线程时一般须要控制线程的并发数,由于线程会消耗系统资源,同时运行的线程过多,系统会变慢app
GCD:
Grand Central Dispatch是由苹果开发的一个多核编程的解决方案。iOS4.0+才能使用,是替代NSThread, NSOperation的高效和强大的技术
GCD是基于C语言的框架
工做原理:
让程序平行排队的特定任务,根据可用的处理资源,安排它们在任何可用的处理器上执行任务
要执行的任务能够是一个函数或者一个block
底层是经过线程实现的,不过程序员能够没必要关注实现的细节
GCD中的FIFO队列称为dispatch queue,能够保证先进来的任务先获得执行
dispatch_notify 能够实现监听一组任务是否完成,完成后获得通知
GCD队列:
全局队列:全部添加到主队列中的任务都是并发执行的
串行队列:全部添加到串行队列中的任务都是顺序执行的
主队列:全部添加到主队列中的任务都是在主线程中执行的异步
全局队列(可能会开启多条线程)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
串行队列(只可能会开启一条线程)
dispatch_queue_t queue = dispatch_queue_create(“myQueue”, DISPATCH_QUEUE_SERIAL);
主队列
dispatch_get_main_queue();async
异步操做
dispatch_async 在其余线程执行任务,会开启新的线程
异步方法没法肯定任务的执行顺序
同步操做
dispatch_sync 在当前在当前线程执行任务,不开启新的线程
同步操做与队列无关
同步方法会依次执行,可以决定任务的执行顺序
更新界面UI时,最好使用同步方法函数
GCD的优势:
充分利用多核
全部的多线程代码集中在一块儿,便于维护
GCD中无需使用@autoreleasepool
若是要顺序执行,能够使用dispatch_sync同步方法spa
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");
});