0

我有一个派生自的类NSThread

@interface FSEventMonitorThread : NSThread {
    FSEventStreamRef m_fseStreamRef;
    CFRunLoopRef m_runLoop;
}

- (id) initWithStream:
    (FSEventStreamRef)fseStreamRef;

- (void) dealloc;

- (void) main;

@end

@implementation FSEventMonitorThread

- (id) initWithStream:
    (FSEventStreamRef)fseStreamRef
{
    if ( self = [super init] )
        m_fseStreamRef = fseStreamRef;
    return self;
}

 - (void) dealloc
{
    CFRunLoopStop( m_runLoop );
    FSEventStreamStop( m_fseStreamRef );
    [super dealloc];
}

- (void) main
{
    m_runLoop = CFRunLoopGetCurrent();
    FSEventStreamScheduleWithRunLoop(
        m_fseStreamRef, m_runLoop, kCFRunLoopDefaultMode
    );
    FSEventStreamStart( m_fseStreamRef );
    CFRunLoopRun();
}

@end

在其他地方(在 C++ 函数内),我创建了一个实例:

m_thread = [[FSEventMonitorThread alloc] initWithStream:m_fseStreamRef];

我的理解是,retain-count 现在应该是 1。在另一个 C++ 函数中,我想停止并释放线程:

[m_thread release];

然而该dealloc方法没有被调用。如果我改为:

[m_thread release];
[m_thread release];

thendealloc被调用,这意味着保留计数为 2。但它是如何变为 2 的?

请注意,NSThread 仅提及使用时保留的文档detachNewThreadSelector:toTarget:withObject:

4

1 回答 1

3

框架本身保持线程的所有权。这是必要的,以便线程对象在 main 方法执行时不会消失。如果你想停止一个线程,你做错了。您必须提供某种线程间通信来向线程的 main 方法发出信号,表明它应该停止正在执行的任何操作、清理并退出。一旦发生这种情况,放弃您对线程的所有权将导致线程释放。您永远不应该简单地过度释放某些东西以使其“消失”。如果你这样做,你几乎肯定不会像本例那样使用提供的对象。

取消线程的一个非常简单的示例可能是:

- (void)finishThread
{
  if( [NSThread currentThread] != self ) // dispatch this message to ourself
    [self performSelector:@selector(finishThread) onThread:self withObject:nil waitUntilDone:NO];
  else
    CFRunLoopStop(CFRunLoopGetCurrent());
}
于 2009-12-08T17:56:47.337 回答