什么时候释放 NSThread 是安全的?

Posted

技术标签:

【中文标题】什么时候释放 NSThread 是安全的?【英文标题】:when is it safe to release an NSThread? 【发布时间】:2009-07-20 03:49:04 【问题描述】:

下面是我的辅助 NSThread* processThread 的运行循环

关闭我调用的线程

//cancel secondary thread
[processThread cancel]
//signal condition
[processCondition broadcast];

然后打电话安全吗:

[processCondition release];
[processThread release];

还是我需要确保线程已经完成? 也许是这样?

NSTimeInterval timeout = [NSDate timeIntervalSinceReferenceDate] + (1.0/15.0);

while ([processThread isExecuting] && [NSDate timeIntervalSinceReferenceDate] < timeout)

    [NSThread sleepForTimeInterval: 1.0/1000.0 ];


[processCondition release];
[processThread release];

详细代码及说明:

- (void)processLoop

    NSAutoreleasePool * outerPool = [[NSAutoreleasePool alloc] init];
    [processCondition lock];

    //outer loop    
    //this loop runs until my application exits
    while (![[NSThread currentThread] isCancelled])    
    
        NSAutoreleasePool *middlePool = [[NSAutoreleasePool alloc];
        if(processGo)
        
            //inner loop
            //this loop runs typically for a few seconds
            while (processGo && ![[NSThread currentThread] isCancelled]) 
            
                NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc]; init];
                //within inner loop
                //this takes a fraction of a second
                [self doSomething];
                [innerPool release];
            
            [self tidyThingsUp];

        
        else
        
            [processCondition wait];
         
        [middlePool release];
    
    [processCondition unlock];      
    [outerPool release];

组合:

内部 while 循环 NSCondition *processCondition 在YESNO 之间切换processGo

允许我在不取消线程的情况下停止并启动内部 while 循环。

if (processGo == YES)

执行进入内部while循环。

当主线程设置时

processGo = NO

执行离开内部的while循环并整理 在外循环的下一轮,执行命中

[processCondition wait]

等待

如果主线程重置

processGo == YES

并调用

[processCondition wait]

执行重新进入内循环

【问题讨论】:

【参考方案1】:

是的,如果你完成了对 NSThread 调用 release 是安全的。在非 GC 目标 C 代码中,习惯用法是,一旦您完成对对象的访问,您就可以释放它。如果还有其他需要该对象的东西,包括对象本身,他们的工作就是保留它。一般来说,如果一个对象不能在任意时间被安全地处置,它会在它处于不安全状态时保留自己,并在可以安全处置时释放自己。

这就是 NSThread 和 NSURLConnection 之类的工作方式(NSURLConnection 实际上保留了它的委托,并做了很多花哨的事情来应对发生的保留循环。

【讨论】:

仅仅因为您“完成”并不意味着线程完全执行完毕。在线程上调用cancel 并不能保证您可以立即释放它。 是的,但是在执行时它会保留自己。 @Louis:你是对的 - 抱歉,没有仔细阅读文档。忽略我最后的评论。 没问题,线程和保留语义是棘手的事情。过去还存在一些非常讨厌的错误和陷阱,使一切变得比文档所暗示的要复杂得多。

以上是关于什么时候释放 NSThread 是安全的?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 NSThread 可以在不创建我自己的 autoreleasepool 的情况下清除自动释放的对象

一条 Objective-C 消息被发送到一个已释放的“NSThread”对象(僵尸),地址为:

使用 [NSThread detachNewThreadSelector:toTarget:withObject:] 时如何设置自动释放池

什么时候在 Excel XLL 中释放 FP * 是安全的?

分配一个 NSThread 然后多次 initWithTarget 线程是不是安全?

NSThread 内存泄漏