代码之家  ›  专栏  ›  技术社区  ›  Paul J. Lucas

NSThread对象保留两次?

  •  0
  • Paul J. Lucas  · 技术社区  · 15 年前

    我有一个派生自 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
    

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

    我的理解是,保留计数现在应该是1。

    [m_thread release];
    

    然而 dealloc 方法不被调用。如果我这样做:

    [m_thread release];
    [m_thread release];
    

    然后 释放内存 调用,这意味着保留计数为2。但它是如何变为2的?

    请注意 仅在使用时提及保留 detachNewThreadSelector:toTarget:withObject: .

    1 回复  |  直到 15 年前
        1
  •  3
  •   Jason Coco superfell    15 年前

    框架本身保留线程的所有权。这是必要的,这样线程对象就不会在主方法执行时消失。如果你想停止一个线程,你是在错误的方式。您必须提供某种类型的线程间通信,以向线程的主方法发出信号,表明它应该停止正在执行的任何操作、清理并退出。一旦发生这种情况,放弃线程的所有权将导致线程解除锁定。你永远不应该简单地过度发布一些东西,让它“消失”。如果您这样做,那么几乎可以肯定的是,您没有按照预期的方式使用所提供的对象,如本例所示。

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

    - (void)finishThread
    {
      if( [NSThread currentThread] != self ) // dispatch this message to ourself
        [self performSelector:@selector(finishThread) onThread:self withObject:nil waitUntilDone:NO];
      else
        CFRunLoopStop(CFRunLoopGetCurrent());
    }