NSThread

Mar 14, 2015


NSThread是什么

线程可以被控制、操作和监控。在iOS中,一个NSThread对象代表一条线程,是控制操作的基本单元。

NSThread可以用来获取线程、控制线程以及创建新的线程,从而完成多线程功能。

获取线程

//获取当前线程
NSThread *currentThread = [NSThread currentThread];
//获取主线程
NSThread *mainThread = [NSThread mainThread];
//是否为主线程,两种方式
[mainThread isMainThread];//实例方法
[NSThread isMainThread];//类方法,表示当前操作是否为主线程
//线程优先级
NSLog(@"主线程优先级 = %f",mainThread.threadPriority);
NSLog(@"当前线程优先级 = %f",[NSThread threadPriority]);
//堆栈信息
NSLog(@"当前线程的堆栈信息%@",[NSThread callStackSymbols]);

创建、启动线程

方法一:alloc 和 init方法

//创建线程,将方法@selector(test:)的操作放在该线程中
NSThread *subThread = [[NSThread alloc]initWithTarget:self selector:@selector(test:) object:@"some thing obj"];
//设置线程name
subThread.name = @"subThread";
//设置线程优先级
subThread.threadPriority = 0.88;
//启动线程
[subThread start];

方法二:静态方法

//创建线程后立即启动
[NSThread detachNewThreadSelector:@selector(test:) toTarget:self withObject:@"etachNewThread"];

方法三:隐式创建线程

[self performSelectorInBackground:@selector(test:) withObject:@"erformSelector"];

线程状态和操作

线程状态

启动线程: - (void)start

线程休眠:两种方法,休眠至某个时间+ (void)sleepUntilDate:(NSDate *)date;休眠多少秒+ (void)sleepForTimeInterval:(NSTimeInterval)ti

强制停止线程:+ (void)exit

线程的安全隐患

同一块资源(内存)可以被多条线程访问,比如访问同一变量、同一对象、同一文件等。当多条线程同时访问一块资源的的时候,非常容易引发数据错乱和数据安全问题。

解决线程安全方法:互斥锁,又叫同步锁,线程同步等

使用方法:@synchronized (锁对象) { 需要锁定的代码 } 这样,锁定的代码同一时间只会被一个线程操作,保证了线程安全。

互斥锁优缺点:

优点:可以有效防止因为多线程抢夺同一块资源造成的数据安全问题。

缺点:需要消耗大量的CPU资源

原子性和非原子性

在iOS的属性申明中,有两个关键词,分别为atomicnonatomic

atomic:原子性,为setter方法加锁,即在set方法中添加@synchronized (self) { setter方法 }

nonatomic:非原子性,不会为setter方法加锁。

注:@property 默认关键词为atomic

线程通讯

在一个进程中,线程之间不是孤立的,需要进行通讯,进行数据传递。比如一个线程传递数据给另一个线程;一个线程执行完成后,转到另一个线程中继续执行任务。

常用用到的方法:

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait