我排干了一个自动释放池。警告*** attempt to pop an unknown autorelease pool表示自动释放池是以不同的方法创建和排出的--这很好。
但这是否意味着这样的池没有被排干呢?有解决方案吗?
发布于 2010-08-15 05:30:48
@itaiferber是不正确的,他链接的Dev博客帖子也是错误的。
不会在堆栈上创建NSAutoreleasePools。它们是在堆上分配的,就像所有其他Cocoa对象一样。
我认为混淆的来源是文档中的内容:
线程每个线程(包括主线程)维护自己的NSAutoreleasePool对象堆栈(参见“
”)。当创建新的池时,它们被添加到堆栈的顶部。当释放池时,它们将从堆栈中删除。
文档中提到的“栈”不是call stack,而是一个stack data structure。这意味着如果你有“自动释放池1",然后创建第二个自动释放池,然后自动释放一个对象,当第二个自动释放池被排出时,该对象将被释放。
总而言之:非常欢迎您在一种方法中创建自动释放池,并在另一种方法中清除它,只要您了解这样做的内存影响。(这是不是一个糟糕的设计完全是另一个问题)
如果您最终没有排出池,那么当父自动释放池被排出时,它将被排出。
如果释放的自动释放池不是堆栈的顶部,则会导致释放堆栈中位于其上的所有(未释放)自动释放池以及它们的所有对象。如果您在使用完成时忽略了将释放发送到自动释放池(不推荐),则当其中一个嵌套的自动释放池被释放时,它将被释放。
因此,如果您的自动释放池堆栈如下所示:
_____
| 1 | <--- most recently allocated pool
|-----|
| 2 |
|-----|
| 3 | <--- least recently allocated pool
-----然后你排出池3,池2和1也会自动排出。我猜这就是你的代码中发生的事情。您正在创建“池1",然后当”池3“被排出时,它会自动排出,然后您试图自己排出池1,但它不再有效,并且您正在”尝试弹出一个未知的自动释放池“。
如果您试图在GUI应用程序中保留自动释放池,那么这个问题尤其明显。在这类应用程序(基于UIKit或AppKit )中,run循环将在每次循环时创建和销毁自动释放池,这意味着在循环迭代期间创建的任何自动释放池都将在下一次循环出现时被销毁。
有关这方面的更多具体信息,请参阅内存管理编程指南中专门介绍自动释放池的an entire section。
https://stackoverflow.com/questions/3484888
复制相似问题