NSThread介绍
NSThread 是苹果官方提供的,使用起来比 pthread 更加面向对象,简单易用,可以直接操作线程对象。不过也需要需要程序员自己管理线程的生命周期(主要是创建),我们在开发的过程中偶尔使用 NSThread。比如我们会经常调用[NSThread currentThread]来显示当前的进程信息。
NSThread的创建与运行
 | 12
 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
 
 | 
简单运用:
| 12
 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
| 12
 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;
 
 | 
线程状态控制方法
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | - (void)start;
 
 
 + (void)sleepUntilDate:(NSDate *)date;
 + (void)sleepForTimeInterval:(NSTimeInterval)ti;
 
 
 + (void)exit;
 
 | 
线程之间的通信
在开发中,我们经常会在子线程进行耗时操作,操作结束后再回到主线程去刷新 UI。这就涉及到了子线程和主线程之间的通信。我们先来了解一下官方关于 NSThread 的线程间通信的方法。
| 12
 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在运行当前线程对象的时候线程任务执行完毕\异常强制退出,则当前线程对象进入死亡状态。