NSAutoreleasePool

1 memory-management objective-c nsautoreleasepool

我抽了一个自动释放池.警告*** attempt to pop an unknown autorelease pool意味着自动释放池是用不同的方法创建和排出的 - 没关系.

但这是否意味着这样的游泳池没有被排干?有解决方案吗?

Dav*_*ong 5

@itaiferber不正确,他链接到的Dev Blog帖子也是如此.

NSAutoreleasePools 不是在堆栈上创建的.它们在堆上分配,就像所有其他Cocoa对象一样.

我认为混淆来自于它在文档中说:

每个线程(包括主线程)都维护自己的NSAutoreleasePool对象堆栈(请参阅"线程").在创建新池时,它们会添加到堆栈顶部.当池被释放时,它们将从堆栈中删除.

文档中提到的"堆栈"不是调用堆栈,而是堆栈数据结构.这意味着如果您有"autorelease pool 1",然后创建第二个自动释放池,然后自动释放一个对象,则在第二个自动释放池耗尽时将释放该对象.

总结:非常欢迎您在一种方法中创建自动释放池并将其排放到另一种方法中,只要您了解这样做的内存含义即可.(这是不好的设计完全是另一个问题)

如果您最终没有耗尽池,那么当父级自动释放池耗尽时,它将会耗尽.

如果释放不是堆栈顶部的自动释放池,则会导致堆栈上方的所有(未释放的)自动释放池及其所有对象一起释放.如果您在完成它时忽略了将释放发送到自动释放池(不建议这样做),则在释放它所嵌套的其中一个自动释放池时释放它.

因此,如果您的自动释放池堆栈如下所示:

 _____
|  1  |  <--- most recently allocated pool
|-----|
|  2  |
|-----|
|  3  |  <--- least recently allocated pool
 -----
Run Code Online (Sandbox Code Playgroud)

然后你排水池3,池2和1也会自动排水.我猜这是你的代码中发生的事情.您正在创建"池1",然后当"池3"耗尽时它会自动耗尽,然后您尝试自己耗尽池1,但它不再有效,并且您"试图弹出一个未知的自动释放池".

这个问题,因为如果您尝试在GUI应用程序中挂起自动释放池,这一点尤为明显.在这样的应用程序(基于UIKit或AppKit)中,运行循环将在循环的每次传递中创建并销毁自动释放池,这意味着在循环迭代期间创建的任何自动释放池将在下一次循环到来时被销毁周围.

有关这方面的更多具体信息,"内存管理编程指南" 的整个部分专门用于自动释放池.