我有一个NSRunLoop对象,我向它附加计时器和流。它运行得很好。但是停止它是另一回事。
我使用[runLoop run]来运行循环。
如果我尝试使用CRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop])停止循环,循环不会停止。如果我改为使用CRunLoopRun()启动循环,它可以正常停止。我还确保在正确的线程上(运行我的自定义运行循环的线程)进行调用。我已经使用pthread_self()调试过了。
我在邮件列表存档中找到了一个开发人员说,“如果你使用NSRunLoop的run方法启动循环,请不要再使用CRunLoopStop()。” 我能理解为什么会是这样 - 通常您需要从同一组函数的初始化程序和终结器中配对。
如何在不使用“CF”的情况下停止NSRunLoop? 我没有看到NSRunLoop上的stop方法。文档说可以通过三种方式停止运行循环:
1.将运行循环配置为使用超时值运行 2.使用CFRunLoopStop()告诉运行循环停止 3.删除所有输入源,但这种方式不可靠,因为您永远无法知道谁在后台将什么卡入运行循环。
好吧,我已经尝试了2. 这种方式感觉“丑陋”,因为您必须深入了解CF。3.就不考虑了-我不喜欢非确定性代码。
这让我们只剩下1. 如果我正确理解文档,您无法向已存在的运行循环“添加”超时。您只能使用超时值运行新的运行循环。如果我运行一个新的运行循环,它将无法解决我的问题,因为它只会创建一个嵌套的运行循环。我仍然会回到旧的运行循环,即我想要停止的那个......对吧?我可能误解了这个。此外,我不想使用超时值运行循环。如果我这样做,我必须在CPU周期(低超时值)和响应性(高超时值)之间进行权衡。
这是我现在的设置(伪代码):
Communicator.h
我使用[runLoop run]来运行循环。
如果我尝试使用CRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop])停止循环,循环不会停止。如果我改为使用CRunLoopRun()启动循环,它可以正常停止。我还确保在正确的线程上(运行我的自定义运行循环的线程)进行调用。我已经使用pthread_self()调试过了。
我在邮件列表存档中找到了一个开发人员说,“如果你使用NSRunLoop的run方法启动循环,请不要再使用CRunLoopStop()。” 我能理解为什么会是这样 - 通常您需要从同一组函数的初始化程序和终结器中配对。
如何在不使用“CF”的情况下停止NSRunLoop? 我没有看到NSRunLoop上的stop方法。文档说可以通过三种方式停止运行循环:
1.将运行循环配置为使用超时值运行 2.使用CFRunLoopStop()告诉运行循环停止 3.删除所有输入源,但这种方式不可靠,因为您永远无法知道谁在后台将什么卡入运行循环。
好吧,我已经尝试了2. 这种方式感觉“丑陋”,因为您必须深入了解CF。3.就不考虑了-我不喜欢非确定性代码。
这让我们只剩下1. 如果我正确理解文档,您无法向已存在的运行循环“添加”超时。您只能使用超时值运行新的运行循环。如果我运行一个新的运行循环,它将无法解决我的问题,因为它只会创建一个嵌套的运行循环。我仍然会回到旧的运行循环,即我想要停止的那个......对吧?我可能误解了这个。此外,我不想使用超时值运行循环。如果我这样做,我必须在CPU周期(低超时值)和响应性(高超时值)之间进行权衡。
这是我现在的设置(伪代码):
Communicator.h
@interface Communicator : NSObject {
NSThread* commThread;
}
-(void) start;
-(void) stop;
@end
Communicator.m
@interface Communicator (private)
-(void) threadLoop:(id) argument;
-(void) stopThread;
@end
@implementation Communicator
-(void) start {
thread = [[NSThread alloc] initWithTarget:self
selector:@selector(threadLoop:)
object:nil];
[thread start];
}
-(void) stop {
[self performSelector:@selector(stopThread)
onThread:thread
withObject:self
waitUntilDone:NO];
// Code ommitted for waiting for the thread to exit...
[thread release];
thread = nil;
}
@end
@implementation Communicator (private)
-(void) stopThread {
CRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop]);
}
-(void) threadLoop:(id) argument {
// Code ommitted for setting up auto release pool
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
// Code omitted for adding input sources to the run loop
CFRunLoopRun();
// [runLoop run]; <- not stoppable with
// Code omitted for draining auto release pools
// Code omitted for signalling that the thread has exited
}
@endif
我该怎么做?在CF中胡乱搞是常见的/好的模式吗?我不太了解Foundation。干涉CF层可能会有危险吗(涉及到内存损坏、不一致和内存泄漏)?有更好的模式可以实现我想要实现的功能吗?
runMode
只运行了一次。重复启动运行循环会产生显著的性能损失吗? - Jörgen Sigvardsson-[NSRunLoop run]
和-[NSRunLoop runUntilDate:]
的工作原理。 - Nicolas Bachschmidt