GCD13 :退出线程和计时器

问题:

你想停止线程或计时器的运行,或者防止再次触发。 

方案:

对于计时器,使用 NSTimer 的实例方法 invalidate。而对于线程,使用 cancel 方法。在线程中避免使用 exit 方法,因为当调用了 exit 之后,线程就没有机会做清理工作,当你的应用程序结束时,会发生资源泄漏。 
NSThread *thread = /* Get the reference to your thread here */; [thread cancel];
NSTimer *timer = /* Get the reference to your timer here */; [timer invalidate];
线程的退出有点复杂。当线程处于休眠状态时,调用了它的 cancel 方法,线程的循环在退出之前仍然会执行完它的全部任务。

 例如:

- (void) threadEntryPoint{
@autoreleasepool {
NSLog(@"Thread Entry Point");
while ([[NSThread currentThread] isCancelled] == NO){ 
[NSThread sleepForTimeInterval:4]; NSLog(@"Thread Loop"); } NSLog(@"Thread Finished");
} }
- (void) stopThread{ NSLog(@"Cancelling the Thread"); [self.myThread cancel]; NSLog(@"Releasing the thread"); self.myThread = nil; } - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.myThread = [[NSThread alloc] initWithTarget:self selector:@selector(threadEntryPoint) object:nil];
[self performSelector:@selector(stopThread) withObject:nil afterDelay:
3.0f]; [self.myThread start];
return YES; }

打印为

...
Thread Entry Point 
Cancelling the Thread
Releasing the thread
Thread Loop Thread Finished
你可以清晰的看到,即使在循环中间 cancel 请求已经触发了,但是我们的线程在退出之前,仍会完成当前的循环。
这是一个非常普遍的陷阱,在执行任务之前,检查线程是否被 cancel 了,可以简单的避免外部影响内部线程的循环。我们通过重写上面的代码,在执行任务前,先检查外部影响,确定线程是否被 cancel 了。如下代码: 

 

- (void) threadEntryPoint{
@autoreleasepool {
    NSLog(@"Thread Entry Point");
    while ([[NSThread currentThread] isCancelled] == NO){ 
        [NSThread sleepForTimeInterval:4];
        if ([[NSThread currentThread] isCancelled] == NO){ 
            NSLog(@"Thread Loop");
           }
        }
    NSLog(@"Thread Finished"); 
    }
}                

 

 

 

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。