Ios 在main中,我生成一个新的NSThread,在main中的稍后某个点,当满足某个条件时,我希望停止该线程。怎样
在命令行程序的主函数中,我创建了一个NSThread子类的新实例,并对其调用start,在不同的线程中运行计时器。如果用户想要停止计时器,他们输入stop,我希望它也结束线程 我该怎么做呢?我想我应该在线程上调用cancel,然后在NSThread子类的main中检查isCancelled是否为YES,但据我所知,main仅在我最初调用start时才被调用。我看不出还有什么地方可以检查isCancelled以调用[NSThread exit] 如何处理退出此NSThread?您可以在NSThread子类中检查isCancelled。您可以在NSThread子类的整个代码中检查isCancelled。调用cancel时,NSThread子类将继续运行,直到检查isCancelled。您要做的是将isCancelled支票放在希望的多个位置,当您调用cancel时,它会点击isCancelled支票并尽快退出 根据您发布的示例代码,我将TimerThread.m改为如下,效果良好:Ios 在main中,我生成一个新的NSThread,在main中的稍后某个点,当满足某个条件时,我希望停止该线程。怎样,ios,objective-c,multithreading,concurrency,nsthread,Ios,Objective C,Multithreading,Concurrency,Nsthread,在命令行程序的主函数中,我创建了一个NSThread子类的新实例,并对其调用start,在不同的线程中运行计时器。如果用户想要停止计时器,他们输入stop,我希望它也结束线程 我该怎么做呢?我想我应该在线程上调用cancel,然后在NSThread子类的main中检查isCancelled是否为YES,但据我所知,main仅在我最初调用start时才被调用。我看不出还有什么地方可以检查isCancelled以调用[NSThread exit] 如何处理退出此NSThread?您可以在NSThre
#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
在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
根据各种注释,您可能需要以下主要方法:
+ (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-否则,您需要内存屏障或其他同步原语,以确保在不同线程上所做的更改在此线程中可见
根据各种注释,您可能需要以下主要方法:
+ (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-否则,您需要内存屏障或其他同步原语,以确保在不同线程上所做的更改在此线程中可见
但是我的NSThread子类只被调用一次,而且据我所知,它只执行一次。一旦它的主函数完成,NSThread就会退出。一旦它完成了,你就不必显式地调用cancel。你能发布代码吗?你的意思是在main方法之外还有其他方法要签入isCancelled吗?下面是一个示例项目,我正在描述这种情况:基本上,我在NSThread子类上调用start,它运行一个计时器。稍晚一点,但在主函数返回之前,我想停止线程,因为不再需要计时器。不过,我与子类交互的唯一时间是启动它,因此我看不出我将在何处放入稍后调用的检查。@DougSmith如果使用计时器,还需要运行循环。运行循环也需要返回,以便您可以从main返回。但是我的NSThread子类只被调用一次,据我所知,只执行一次。NSThread将在其主函数完成后退出。一旦它完成了,你就不必显式地调用cancel。你能发布代码吗?你的意思是在main方法之外还有其他方法要签入isCancelled吗?下面是一个示例项目,我正在描述这种情况:基本上,我在NSThread子类上调用start,它运行一个计时器。稍晚一点,但在主函数返回之前,我想停止线程,因为不再需要计时器。不过,我与子类交互的唯一时间是启动它,所以我看不到
我将支票放在什么地方,稍后会调用。@DougSmith如果你使用计时器,你还需要一个运行循环。运行循环也需要返回,这样您就可以从main返回。NSThread在主函数返回后终止。@CouchDeveloper我希望它在此之前终止。您必须提前从main返回的唯一选项由@random Ready非常准确地描述。NSThread在主函数返回后终止。@CouchDeveloper我希望它在此之前终止那就是,@random ready.+1说得很好的@CouchDeveloper这实际上帮助我调整了一个现有的项目:P@random出于好奇:你能解决什么问题?我一直在研究将大量数据解析为CoreData的最佳方法,并获得了一些经验NSOperation子类共享工作负载。我使用的解决方案与我向他提供的类似,但您发布的内容让我找到了另一种可能更干净的解决方案+1说得好@CouchDeveloper这实际上帮助我调整了一个现有的项目:P@random出于好奇:您能解决什么问题?我一直在研究将大量数据解析为CoreData的最佳方法,并让一些NSOperation子类共享工作负载。我使用的解决方案与我向他提供的类似,但您发布的内容让我找到了另一种可能更干净的解决方案