我正在构建一个iPhone应用程序,其中我分离了一些线程,以便在后台执行长时间运行的工作,这样就不会挂起UI。我知道线程需要NSAutoreleasePool实例来进行内存管理。我不确定的是,线程方法是否调用了另一个方法--该方法是否也需要一个NSAutoreleasePool?
示例代码:
- (void)primaryMethod {
[self performSelectorInBackground:@selector(threadedMethod) withObject:nil];
}
- (void)threadedMethod {
NSAutoreleasePool *aPool = [[NSAutoreleasePool alloc] init];
// Some code here
[self anotherMethod];
// Maybe more code here
[aPool drain];
}
- (void)anotherMethod {
// More code here
}我问这个问题的原因是,我收到了一些错误,即对象正在自动释放,而没有设置池,并且“只是在泄漏”。
我见过其他问题,人们根本没有自动释放池,我理解为什么需要自动释放池。我特别感兴趣的是,在threadedMethod中创建的自动释放池(在本例中)是否适用于在anotherMethod中创建的对象。
发布于 2009-06-18 05:13:47
回答你的问题,是的,anotherMethod正在使用你在threadedMethod中创建的NSAutoreleasePool,你在那里自动释放的任何东西都将在aPool释放/排出时释放。
因此,您的错误不太可能直接源于此代码(除非还有更多的问题)。
在_NSAutoreleaseNoPool上放置一个断点(在断点窗口中按名称添加),然后在调试器中运行代码,当在没有池的情况下调用自动释放时,调试器将停止,这应该可以解决您的问题。
发布于 2010-05-12 13:42:35
在您的示例中,是的,NSAutoreleasePool跨方法传递,因为[self anotherMethod]的调用嵌套在-(void)threadedMethod中。
无论如何,当父作用域消失时,NSAutoreleasePool实例本身就会超出作用域。在-(void)threadedMethod { }的最后,-in你的例子。
前面提到的文章(http://thegothicparty.com/dev/macos/nsautoreleasepool/)对此非常清楚。
发布于 2009-06-18 03:28:43
自动释放池确实延续到了anotherMethod。但是,当您的线程化函数结束时,您应该调用aPool release而不是aPool drain。它们大致相同,但aPool释放会导致NSAutoreleasePool除了释放池中的所有其他对象之外,还会释放自身。当你的线程函数在调用drain后结束时,自动释放池仍然有一个+1的保留计数!很有可能,“泄漏”的对象是aPool!
编辑:
Jim Puls是对的,释放和排出是等价的。Apple文档明确表示,它们在非垃圾收集环境中是相同的,而排出在垃圾收集环境中更好。不读文档是我的错!
这里有一篇文章,介绍了NSAutoreleasePools的一般概述-它应该可以帮助您找到正确的方向。因为有一个自动释放池的虚拟堆栈,最上面的一个将在你的应用程序中的任何地方使用-无论对象在哪里被自动释放。
http://thegothicparty.com/dev/macos/nsautoreleasepool/
https://stackoverflow.com/questions/1010629
复制相似问题