2014-01-15 13 views
0

在我的命令行程序的主要功能中,我创建了一个NSThread子类的新实例,并在其上调用start,它在不同的线程中运行计时器。如果用户想停止计时器,他们键入“停止”,我也希望它终止该线程。在主要我产生一个新的NSThread,并在稍后的主要条件时遇到我想停止线程。怎么样?

我该怎么做呢?我正在收集,我应该在线程上调用cancel,然后在NSThread子类的main中检查isCancelled是否为YES,但据我所知main只在最初调用start时调用。我没有看到我可以检查isCancelled以便拨打[NSThread exit]

我应该如何处理退出此NSThread?

+0

NSThread在主函数返回后终止。 – CouchDeveloper

+0

@CouchDeveloper我想在此之前终止。 –

+0

您必须从'main' *过早返回的唯一选项*已被@random完全描述。 – CouchDeveloper

回答

3

您在NSThread子类中检查isCancelled。您在NSThread子类中的整个代码中检查isCancelled。当您致电cancel时,您的NSThread子类继续运行,直到它遇到isCancelled的检查。你所做的是将isCancelled检查多个地方希望当你打电话cancel它击中isCancelled检查并尽快退出。

从你的示例代码,你贴我改变了TimerThread.m看起来像这样和正常工作:

#import "TimerThread.h" 
#import "Giraffe.h" 

@interface TimerThread() { 
    Giraffe *giraffe; 
} 

@end 

@implementation TimerThread 

- (void)main { 

    if (self.isCancelled) 
     return; 

    giraffe = [[Giraffe alloc] init]; 

    [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(calculate:) userInfo:nil repeats:YES]; 

    [[NSRunLoop currentRunLoop] run]; 
} 

- (void)calculate:(NSTimer*)timer { 
    if (self.isCancelled) { 

     [timer invalidate]; 

     return; 
    } 

    [giraffe calculateValues:timer]; 
} 

@end 
+0

但是我的NSThread子类只被调用一次,并且据我所知只能执行一次。 –

+0

一旦主功能完成,'NSThread'就会退出。一旦完成,你不必显式调用'cancel'。 – random

+0

你可以发布代码吗?你是否意味着你有''main'方法之外的其他方法需要检查'isCancelled'? – random

1

基础上的各种评论,你可能想要一个主要方法如下:

+ (void) threadMain 
{ 
    @autoreleasepool { 
     [[NSThread currentThread] setName:@"WorkerThread.sharedThread"]; 
     NSRunLoop* runLoop = [NSRunLoop currentRunLoop]; 
     [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; 
     BOOL done = NO; 
     while (!done) { 
      @autoreleasepool { 
       [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
       // check termination status: 
       done = ...; 
      } 
     } 
    } 
} 

一些解释:

  • [runLoop addPort:port]Ë确保运行循环至少有一个事件源,否则,运行循环可能会过早返回。

  • 运行循环在每个处理过的事件源之后返回。也就是说,您可以在发生某些事情后检查状态(例如,在此运行循环中计划的计时器,其模式等于NSDefaultRunLoopMode)。

  • 内自动释放池是必需的,因为[NSDate distantFuture]返回自动释放对象 - 这可能叠加起来,除非你有一个自动释放池。

  • 可变done必须从执行在此线程代码中设置 - 否则,你需要记忆障碍或其他同步原语,以确保在不同的线程进行了更改,在这个线程是“看得见”。

+0

+1好说@CouchDeveloper这实际上帮助我调整了一个现有的项目:P – random

+0

@random出于好奇:你能解决什么问题? – CouchDeveloper

+0

我一直在使用最佳的方式来解析大量的数据到CoreData中,并且有一些NSOperation子类共享工作负载。我正在使用与我提供的解决方案相似的解决方案,但是您发布的内容让我可以找到更清晰的解决方案。 :) – random

相关问题