iOS多线程相关码无界IOS And AndroidiOS学习笔记

iOS多线程讲解一之NSThread

2016-04-05  本文已影响191人  kevinLY

本文主要参考Apple官方文档,英文好的可以直接看官方文档

一个NSThread对象控制一个线程的执行。当你想有一个OC方法运行在它自己的线程中,你可以使用这个类。线程是特别有用,当您需要执行一个冗长的任务,但是不想让它阻止执行应用程序的其余部分。特别是,您可以使用线程来避免阻塞应用程序的主线程,处理用户界面交互和与事件相关的方法。线程也可以用来将大量的工作分成几个较小的工作,从而提高多核计算机的性能。
在OSXv10.5以前,唯一一个启动线程的方法是使用detachNewThreadSelector:toTarget:withObject:,在OSX10.5及以后,你可以创建一个NSThread实例,然后调用start方法启动它。
在OSXv10.5 ,该NSThread类支持用NSOperation的监测线程的运行状态。您可以使用NSOperation取消线程的执行或确定线程是否仍在执行或已经完成了它的任务。取消一个线程需要来自你的线程代码的支持。
在 OSXv10.5 及以后,你可以子类化NSThread,并且重写main方法来实现你的线程入口。如果你重新了main方法,你没有必要再通过super去调用父类。

-(instanceType)init;
NSThread *thread = [[NSThread alloc] init];

- (nullable instancetype)initWithTarget:(id)target
                               selector:(SEL)sel 
                                 object:(nullable id)arg;
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadAction:) object:nil];
+ (void)detachNewThreadSelector:(SEL)selector 
                       toTarget:(id)target 
                     withObject:(nullable id)argument;

NOTE:aTarget 和 anArgument 在分离出来的线程的执行过程中被保留,然后释放。一旦aTarget执行完aSelector方法,分离出来的线程就会退出(使用exit方法)。
如果线程是第一次被从应用中分离出来,这个方法就会往默认的通知中心发送一个通知NSWillBecomeMultiThreadedNotification。

- (void)start;

NOTE:调用这个方法将产生一个新的线程、并且调用接收者的main方法。如果你使用target和selector初始化接收者,那么main方法将会自动调用selector方法。
如果线程是第一次被从应用中分离出来,这个方法就会往默认的通知中心发送一个通知NSWillBecomeMultiThreadedNotification。

- (void)main;

NOTE: 这个方法默认的实现是用target和selector方法初始化接收者,并且在特定的接收者里面调用selector方法,如果你子类化NSThread类,你可以重写main方法,并且实现它。如果你这样做,你就没有必要调用super。
你绝不能直接调用mian方法,你应该通过调用start方法启动你的线程。

//date:恢复线程的时间
+ (void)sleepUnitDate:(NSDate *)date;
//线程暂停的时长
+(void)sleepForTimeInterval:(NSTimeIntrval)ti;
- (void)exit;

NOTE:这个方法使用currentThread类方法访问当前线程。在退出这个线程之前,这个方法往默认的通知中心发送带有线程退出内容的通知NSThreadWillExitNotification。 因为通知是被同步的发送的,所以能保证通知NSThreadWillExitNotification的所有观察者在线程退出之前能收到通知,因为线程不会清理在运行过程中申请的资源,所有应该避免使用这个方法。

- (void)cancel;

NOTE:改变接收者的取消状态以表明线程将要退出。

//一个用于判断线程是否正在执行的布尔值(只读)
@property(readonly, getter=isExecuting) BOOL executing 
//一个用于判断线程是否执行完成的布尔值(只读)
@property(readonly, getter=isFinished) BOOL finished  
//一个用于判断线程是否被取消的布尔值(只读)
@property(readonly, getter=isCancelled) BOOL cancelled  
说明:如果你的线程支持取消,那么你需要定期的检查线程的状态,并且如果isCancelled为YES,就调用exit退出。
//判断当前线程是否是主线程
- (BOOl)isMainThread;
//返回当前的主线程
+ (NSThread *)mainThread;
//判断当前应用是否是多线程应用
+ (BOOL)isMutiThreaded;

NOTE:在应用中,如果你使用方法detachNewThreadSelector:toTarget:withOb
ject:
start创建一个线程,那么这个应用就是多线程应用,如果你使用non-CocoaAPI,例如POSIX或Multiprocessing Services APIs,那么这个应用就不是多线程应用。

//返回表示当前正在执行的线程对象
+ (NSThread *)currentThread;
//返回包含调用堆栈返回地址的数组。
+ (NSArray<NSNumber *> *)callStackReturnAddresses;

返回一个包含调用堆栈返回地址的数组,每一个元素是一个包含NSUInteger值的NSNumber对象。

//返回包含堆栈调用符号的数组
+(NSArray<NSSTring *> *)callStackSymbols;

NOTE:返回包含堆栈调用符号的数组.每个元素是由backtrace_symbols函数确定格式的值的一个NSString对象。

//返回线程对象的字典
@property(readonly, retain) NSMutableDictionary *threadDictionary;

NOTE:您可以使用返回的字典存储特定线程的数据。线程字典在线程的任何操作期间不能够被使用-它只是用来存储一些你想要存储的数据。例如:Foundation用它来存储线程的默认NSConnection连接和NSAssertionHandler实例。你可以自定义你字典的keys。

//接收者的名字
@property(copy) NSString *name;
//接收器的堆栈大小,以字节为单位
@property NSUInteger stackSize;

NOTE:该值必须以字节为单位,并且是4KB的倍数。如果你要改变堆栈大小,你必须在你开始你的线程之前设置这个属性。如果你在线程启动之后在设置堆栈属性,会改变属性的大小(这是通过 stackSize方法反应的),但是不会影响预留线程的实际页数。

//返回当前线程的优先级
+(double)priority;

NOTE:returnValue:返回当前线程的优先级,取值范围是[0.0 1.0],1.0是最高优先级。
在此范围内的优先级被映射到操作系统的优先级值。 “典型”的线程优先级可能是0.5 ,但由于优先级由内核决定的,但不保证此值实际上将是什么。

//设置线程的优先级
+ (BOOL)setThreadPriority:(double) priority;
NSDidBecomeSingleThreadedNotification

NOTE:当一个线程收到exit命令时,在线程退出之前,它会发送这个通知。收到这个通知的观察者会在线程退出前执行退出方法。
通知对象是离开的NSThread对象。这个通知不包含userInfo字典信息。

NSThreadWillExitNotification

NOTE:当有一个线程从当前线程中分离出去的时候发送这个通知。NSThread类最多只能发送一次这个通知,在第一次使用 detachNewThreadSelector:toTarget:
withObject:
或者使用方法start的时候。后续这些方法的调用不会再次发送该通知。这些观察者在主线程中调用他们的通知方法,而不是在新线程中,观察者的通知方法总是在执行新线程开始执行之前执行。
这个通知不包含userInfo字典信息。

上一篇 下一篇

猜你喜欢

热点阅读