NSThread介绍
NSThread 是苹果官方提供的,使用起来比 pthread 更加面向对象,简单易用,可以直接操作线程对象。不过也需要需要程序员自己管理线程的生命周期(主要是创建),我们在开发的过程中偶尔使用 NSThread。比如我们会经常调用[NSThread currentThread]来显示当前的进程信息。
NSThread的创建与运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| - (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument - (instancetype)initWithBlock:(void (^)(void))block
+ (void)detachNewThreadWithBlock:(void (^)(void))block
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument
|
简单运用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| - (void)viewDidLoad { [super viewDidLoad]; NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(firstThread:) object:@"Hello, World"]; [thread setName:@"firstThread"]; [thread start]; }
- (void)firstThread:(id)arg { NSLog(@"Task %@ %@", [NSThread currentThread], arg); NSLog(@"Thread Task Complete"); }
|
常见API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| + (NSThread *)mainThread;
- (BOOL)isMainThread;
+ (BOOL)isMainThread;
NSThread *current = [NSThread currentThread];
- (void)setName:(NSString *)n;
- (NSString *)name;
|
线程状态控制方法
1 2 3 4 5 6 7 8 9
| - (void)start;
+ (void)sleepUntilDate:(NSDate *)date; + (void)sleepForTimeInterval:(NSTimeInterval)ti;
+ (void)exit;
|
线程之间的通信
在开发中,我们经常会在子线程进行耗时操作,操作结束后再回到主线程去刷新 UI。这就涉及到了子线程和主线程之间的通信。我们先来了解一下官方关于 NSThread 的线程间通信的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13
| - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray<NSString *> *)array;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array NS_AVAILABLE(10_5, 2_0); - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);
- (id)performSelector:(SEL)aSelector; - (id)performSelector:(SEL)aSelector withObject:(id)object; - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
|
线程的状态转换
当我们新建一条线程NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];,在内存中的表现为:
当调用[thread start];后,系统把线程对象放入可调度线程池中,线程对象进入就绪状态,如下图所示。
- 如果CPU现在调度当前线程对象,则当前线程对象进入运行状态,如果CPU调度其他线程对象,则当前线程对象回到就绪状态。
- 如果CPU在运行当前线程对象的时候调用了sleep方法\等待同步锁,则当前线程对象就进入了阻塞状态,等到sleep到时\得到同步锁,则回到就绪状态。
- 如果CPU在运行当前线程对象的时候线程任务执行完毕\异常强制退出,则当前线程对象进入死亡状态。