在OC中,虽然使用NSThread的实际场景不多,但如果能够在学习多线程的时候,仔细的了解NSThread的方法,可以对后面深入学习GCD与NSOperation会大有帮助.今天讨论一下关于线程的状态一些情况:
一个线程在内存中的状态,NSThread提供了大体三种处理方式:取消(cancel),休眠(sleep),以及退出(exit)
下面简单梳理一下这几种情况:
1. - (void)cancel // 取消
这个方法会将正在执行的当前进程信息保存给接收者,然后再将进程取消,同时会通过方法isCancled反馈状态,如果成功取消,isCancled将会返回YES,否则返回NO;
进程被取消后,会调用exit方法;
2.+ (void)sleepUntilDate:(NSDate *)aDate // 休眠进程
这个方式NSThread的静态方法;它根据给定的时间(aDate)阻塞当前进程的执行,它实现的底层原理是阻塞了进程的runloop的运行,这样当前进程就无法获得执行的机会;
与此类似的,还有一个静态方法:+ (void)sleepForTimeInterval:(NSTimeInterval)ti,它们的使用原理是一样的.
3.+ (void)exit // 退出进程
这个方法会调用NSThread的类方法 currentThread来访问当前进程,这样做的一个目的是为了让当前进程可以发送一个通知 (NSThreadWillExitNotification)
给通知中心.
这个方法可以手动调用,也可以等进程正常执行结束会自动调用.
在手动调用这个进程时,一定要提前释放之前申请的资源;否则容易产生内存泄漏;
同时NSThread也提供了三个查询进程执行状态的方法:
1.- (BOOL)isExecuting
如果进程正在执行,这个方法返回YES,否则返回NO;
2.- (BOOL)isFinished
如果进程执行结束,返回YES,否则返回NO;
3.- (BOOL)isCancelled
如果进程被取消,返回YES,否则返回NO;
在OC中,NSThread的状态变化,都会在内部使用消息通知机制来告知系统,并且NSThread只会发送三种消息到系统的通知中心:
1.NSDidBecomeSingleThreadedNotification
这个通知目前没有实际意义,苹果也仅仅是保留这个扩展通知而已,并没有在NSThread的方法中,来触发这个消息,不过根据这个通知的字面意思来理解,是进程又回到单一线程的 时候,会发送这个通知;但在多线程环境下, 这个没有什么实际的处理工作,可暂时忽略;
2.NSThreadWillExitNotification
这个通知被发送到通知中心的时候,并没有包含userinfo的字典信息(使用通知中心的伙伴们都应该知道userinfo滴,偶就不解释啦),并且这个通知是在进程执行exit方法的时候触发 的.你可以通过监听这个通知来处理一下进程即将结束之前的一些事情(就像遗言一样).
3.NSWillBecomeMultiThreadedNotification
这个通知只会被NSThread触发一次,条件是当第一个进程在调用了start或者detachNewThreadSelector:toTarget:withObject:方法.这个通知的接收者的一些处理方法都是在主 线程上进行的;这是因为这个通知是在系统生产新的子线程之前进行的,所以在监听这个通知的时候,调用监听者的通知方法都会在主线程进行.
其实NSThread提供的这些基本方法和状态通知,我们可以大体的了解进程一个生命周期,并且在这个生命周期中,进程经过了什么状态的转变,以及进程间简单的交互(使用通知中心),这对我们以后在使用GCD以及NSOperate的时候,能够更好的理解它们的内部实现基本原理.
在开发中,往往是一个小的细节里,蕴含着内部的整个机制.这需要我们不断的自主思考,猜测,验证,然后乐在其中....