前言
每一个iOS应用程序都有个专门用来更新显示UI界面、处理用户触摸事件的主线程。因此不能将其它太耗时的操作放在主线程中运行,不然会造成主线程阻塞(出现卡机现象)。带来极坏的用户体验。一般的解决方式就是将那些耗时的操作放到另外一个线程中去运行,多线程编程是防止主线程阻塞,添加运行效率的最佳方法。
iOS中有3种常见的多线程编程方法:
1.NSThread
这样的方法须要管理线程的生命周期、同步、加锁问题。会导致一定的性能开销
2.NSOperation和NSOperationQueue
是基于OC实现的。NSOperation以面向对象的方式封装了须要运行的操作。然后能够将这个操作放到一个NSOperationQueue中去异步运行。不必关心线程管理、同步等问题。
3.Grand Centeral Dispatch
简称GCD,iOS4才開始支持,是纯C语言的API。
自iPad2開始,苹果设备開始有了双核CPU,为了充分利用这2个核,GCD提供了一些新特性来支持多核并行编程
这篇文章简介NSThread这个类。一个NSThread实例就代表着一条线程
一、获取当前线程
NSThread *current = [NSThread currentThread];
二、获取主线程
1 NSThread *main = [NSThread mainThread]; 2 NSLog(@"主线程:%@", main);
打印结果是:
2013-04-18 21:36:38.599 thread[7499:c07] 主线程:<NSThread: 0x71434e0>{name = (null), num = 1}
num相当于线程的id,主线程的num是为1的
三、NSThread的创建
1.动态方法
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
* 在第2行创建了一条新线程。然后在第4行调用start方法启动线程,线程启动后会调用self的run:方法,而且将@"mj"作为方法參数
1 // 初始化线程 2 NSThread *thread = [[[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"mj"] autorelease]; 3 // 开启线程 4 [thread start];
假如run:方法是这种:
1 - (void)run:(NSString *)string { 2 NSThread *current = [NSThread currentThread]; 3 NSLog(@"运行了run:方法-參数:%@,当前线程:%@", string, current); 4 }
打印结果为:
2013-04-18 21:40:33.102 thread[7542:3e13] 运行了run:方法-參数:mj,当前线程:<NSThread: 0x889e8d0>{name = (null), num = 3}
能够发现,这条线程的num值为3。说明不是主线程,主线程的num为1
2.静态方法
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"mj"];
运行完上面代码后会立即启动一条新线程,而且在这条线程上调用self的run:方法。以@"mj"为方法參数
3.隐式创建线程
[self performSelectorInBackground:@selector(run:) withObject:@"mj"];
会隐式地创建一条新线程。而且在这条线程上调用self的run:方法,以@"mj"为方法參数
四、暂停当前线程
[NSThread sleepForTimeInterval:2];
NSDate *date = [NSDate dateWithTimeInterval:2 sinceDate:[NSDate date]]; [NSThread sleepUntilDate:date];
上面两种做法都是暂停当前线程2秒
五、线程的其它操作
1.在指定线程上运行操作
1 [self performSelector:@selector(run) onThread:thread withObject:nil waitUntilDone:YES];
* 上面代码的意思是在thread这条线程上调用self的run方法
* 最后的YES代表:上面的代码会堵塞,等run方法在thread线程运行完成后,上面的代码才会通过
2.在主线程上运行操作
[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES];
在主线程调用self的run方法
3.在当前线程运行操作
[self performSelector:@selector(run) withObject:nil];
在当前线程调用self的run方法
六、优缺点
1.长处:NSThread比其它多线程方案较轻量级。更直观地控制线程对象
2.缺点:须要自己管理线程的生命周期,线程同步。
线程同步对数据的加锁会有一定的系统开销