您的位置:首页 > 移动开发 > IOS开发

IOS 多线程

2016-03-07 00:00 501 查看
摘要: IOS 多线程

1、NSObject的多线程方法——后台线程

2、NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程)
以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题
3、NSOperation/NSOperationQueue 面向对象的线程技术
4、GCD —— Grand Central Dispatch(派发) 是基于C语言的框架,可以充分利用多核,是苹果推荐使用的多线程技术

NSThread:
优点:NSThread 比其他两个轻量级,使用简单
缺点:需要自己管理线程的生命周期、线程同步、加锁、睡眠以及唤醒等。线程同步对数据的加锁会有一定的系统开销

NSOperation:
不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上
NSOperation是面向对象的

工作原理:
用NSOperation封装要执行的操作
将创建好的NSOperation对象放NSOperationQueue中
启动OperationQueue开始新的线程执行队列中的操作
注意事项:
使用多线程时通常需要控制线程的并发数,因为线程会消耗系统资源,同时运行的线程过多,系统会变慢

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();

异步操作
dispatch_async 在其他线程执行任务,会开启新的线程
异步方法无法确定任务的执行顺序
同步操作
dispatch_sync 在当前在当前线程执行任务,不开启新的线程
同步操作与队列无关
同步方法会依次执行,能够决定任务的执行顺序
更新界面UI时,最好使用同步方法

GCD的优点:
充分利用多核
所有的多线程代码集中在一起,便于维护
GCD中无需使用@autoreleasepool
如果要顺序执行,可以使用dispatch_sync同步方法

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");

});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: