iOS开发中不能将太耗时的操作放在主线程中执行,否则会造成线程的阻塞。通常解决方案就是将耗时的操作另开一个线程执行。
iOS 支持多个层次的多线程编程,层次越高的抽象程度越高,使用起来也越方便,也是苹果最推荐使用的方法。下面根据抽象层次从低到高依次列出iOS所支持的多线程编程范式:
- Thread :是三种方法里面相对轻量级的,但需要管理线程的生命周期、同步、加锁问题,这会导致一定的性能开销。
-
Cocoa Operations:是基于OC实现的,NSOperation以面向对象的方式封装了需要执行的操作,不必关心线程管理、同步等问题。NSOperation是一个抽象基类,iOS提供了两种默认实现:
NSInvocationOperation
和NSBlockOperation
,当然也可以自定义NSOperation。 - GCD(iOS4才开始支持):提供了一些新特性、运行库来支持多核并行编程,它的关注点更高:如何在多个cpu上提升效率。
一、创建NSthread
NSThread的创建主要有3种直接方式:
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
// 调用完毕后,会马上创建并开启新线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[thread start]; // 开启线程
[self performSelectorInBackground:@selector(run) withObject:nil];
第一种会立即创建一个线程来做事情;第二种虽然你 alloc
了也init
了,但是要直到我们手动调用start
启动线程时才会真正去创建线程。这种延迟实现思想在很多跟资源相关的地方都有用到,还可以在启动线程之前,对线程进行配置,比如设置stack
大小,线程优先级。第三种间接的方式,更加方便,我们甚至不需要显式编写 NSThread 相关代码。
二、NSthread常用方法:
NSThread *current = [NSThread currentThread]; //获取当前线程
NSThread *main = [NSThread mainThread]; //获取当前主线程
[NSThread sleepForTimeInterval:2]; // 暂停2s
NSDate *date = [NSDate dateWithTimeInterval:2 sinceDate:[NSDate date]];
[NSThread sleepUntilDate:date];// 暂停2s
三、线程间通信
//主线程上执行操作:
[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES];
//当前线程上执行操作:
[self performSelector:@selector(run) onThread:thread withObject:nil waitUntilDone:YES];
//指定线程上执行操作:
[self performSelector:@selector(run) onThread:thread withObject:nil waitUntilDone:YES];
所谓线程间通信,即如何从一个线程进入到另一个线程继续执行任务或者是传递参数(如从子线程回到主线程)。