目标 C - NSthread 和 NSAutoreleasePool?

Posted

技术标签:

【中文标题】目标 C - NSthread 和 NSAutoreleasePool?【英文标题】:Objective C - NSthread & NSAutoreleasePool? 【发布时间】:2010-10-28 21:20:56 【问题描述】:

编写线程安全方法的最佳方法是什么?

我有以下方法,有时我想异步调用它(通过线程调用它) 有时我想直接在主线程上调用它。 即使我没有在单独的线程上调用该方法,保留池(分配、释放)是否有问题?

- (void)doStuff

     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
     //do some stuff here?
     [pool release];

【问题讨论】:

在房间里的大象中,您是否有游泳池是一个如此微不足道的细节; “如何编写线程安全的方法?”回答 that 中的详细信息数量可能会构成整个 *** 标记本身! 【参考方案1】:

在主线程上调用是完全安全的。 NSAutoreleasePool 维护一个堆栈,因此在这种情况下,您只需在堆栈顶部放置一个新池,然后在完成后将其弹出。

【讨论】:

【参考方案2】:

不,始终使用您自己的本地方法池没有问题。不过,您应该使用[pool drain] 而不是[pool release]

【讨论】:

澄清一下,[pool drain][pool release] 在手动内存管理下是一样的,但是在 GC 下,前者会触发一个收集,而后者是一个空操作。 正确,但对于所有面向 10.4 或更高版本的开发,我认为没有理由不总是更喜欢 -drain 而不是 -release【参考方案3】:

不管它对发布池意味着什么,我都不建议这样写。如果您绝对必须能够从主线程和其他线程调用该方法,请编写如下代码:

- (void) doSomething 


- (void) doSomethingInBackground 
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    [self doSomething];
    [pool release]

这样,您将方法包装在一个负责释放池的方法中。

【讨论】:

【参考方案4】:

我也更喜欢 Ivo Jansch 提到的方法。创建/清空池是有效的,但是当您调用方法 doStuff: 递归或多次时可能会有点头疼。但是通过遵循 Ivo 的方法,您可以在没有记忆问题的情况下做一些事情。 而且对于线程安全的方法,您必须在需要时使用锁或@synchronized(),通常是在访问数组/缓冲区/字典时。你的方法应该是这样的

- (void)doStuff
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];

 @synchronized(lock) 
 
    NSLog(@"Hello World");
 
 [pool release];

【讨论】:

以上是关于目标 C - NSthread 和 NSAutoreleasePool?的主要内容,如果未能解决你的问题,请参考以下文章

iOS学习——多线程开发(NSThread)

ios30---pthread, NSThread, GCD, NSOperation

如何“手动”符号化 [NSThread callStackSymbols](获取 atos 的起始地址)(iOS)

多线程之pthread, NSThread, NSOperation, GCD

iOS的三种多线程技术NSThread/NSOperation/GCD

NSThread