尝试弹出未知的自动释放池

时间:2010-06-21 22:37:30

标签: iphone core-data

有谁知道这个错误意味着什么? ***尝试弹出一个未知的自动释放池

我在我的应用程序中看到这个在NSOperationQueue中使用NSOperations。每个操作都有自己的Autorelease池。由于每个操作都在解析xml并将信息推送到Core Data中,因此我会定期“排空”我的自动释放池并重新创建它。如果我不排水池,我不会看到这些错误。

更新: 这是我的代码:

在我的NSOperation的主要内容中,我分配了池并将其分配给'assign'属性,如下所示:

self.downloadAndParsePool = [[NSAutoreleasePool alloc] init];

在我的主要结尾处,我这样发布:

[self.downloadAndParsePool release];
self.downloadAndParsePool = nil;

如果操作进行了大量的解析并插入到Core Data中,它会定期调用我的drain方法:

- (void) drainAutoreleasePool
{
    // drain and re-create autorelease pool...this method is called periodically to keep memory down during parsing of large trees
    if (self.downloadAndParsePool)
    {
        [self.downloadAndParsePool drain];
        self.downloadAndParsePool = [[NSAutoreleasePool alloc] init];
    }
}

5 个答案:

答案 0 :(得分:4)

似乎这个问题是由于即使在同一个线程上,在分配池的方法之外调用了漏极的事实。以下是NSAutoreleasePool Class Reference所说的内容。

  

你应该总是消耗自动释放   池在同一个上下文中(调用   方法或功能,或身体的   它创建了。

您看到的消息是由您在drainAutoreleasePool:

中的排水呼叫触发的
[self.downloadAndParsePool drain];

注意:XMLPerformance示例应用程序使用相同的模式定期耗尽池。它自iOS4.0起生成此消息

答案 1 :(得分:2)

如何解决此问题

这里接受的答案是正确的,但是这里有一些关于如何修复它的更多细节,因为仅仅存在填满控制台的问题并不是一个好主意。正在打印日志声明,这是有原因的。有点不对劲。

原来这个代码来自Apple自己的名为XMLPerformance的示例项目,可在此处找到:http://developer.apple.com/library/ios/#samplecode/XMLPerformance/Introduction/Intro.html

在源文件LibXMLParser.m中,只需更改以下行:

self.downloadAndParsePool = [[NSAutoreleasePool alloc] init];

到此:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

- (void)downloadAndParse:(NSURL *)url方法的开头,然后更改:

[downloadAndParsePool release];
self.downloadAndParsePool = nil;

到此:

[pool release], pool = nil;

在该方法的最后。现在删除名为downloadAndParsePool的ivar。完成所有这些后,消息就会消失。

神奇美味。

答案 2 :(得分:0)

听起来你在某个地方失去了一个游泳池。池是对象,它们可能会过度释放。它们也以一种方式堆叠。 IIRC,当您有嵌套池时,排空外部池会自动耗尽内部池。我认为你有一个游泳池对象在没有耗尽的情况下死亡。当外池试图耗尽它时,它永远不会得到响应。

只是一个猜测。

答案 3 :(得分:0)

如果您可以显示创建池,池的消耗和重新创建池的代码,那将非常有用。否则我们只是猜测答案。

更新

首先,像这样的池应该是-main内的局部变量,而不是像那样的iVar。其次,您的财产如何定义?是分配还是保留?

UPDATE2

我仍然建议不要使用iVar存储该池。然而,因为它是一个应该没问题的指定。

当你耗尽游泳池时,你是否也在保存并重置与该操作相关的NSManagedObjectContextNSManagedObjectContext非常大量地使用自动释放池,如果你没有在可能导致错误的排放的同时重置它。

UPDATE3

好的,然后我们留下了TechZen的建议,即你正在某个地方失去一个游泳池。我会在你创建一个池之后放入日志语句并吐出它的指针地址,并在排放之前放入一个日志语句,同时吐出指针地址。然后匹配它们。如果他们匹配,那么泄漏就在其他地方。

答案 4 :(得分:0)

如果您使用NSAutoReleasePool

创建了一个池

这样它就会自动释放 无需在dealloc

中发布

如果您使用NSAutoReleasePool,应用有时会崩溃 并在dealloc

中释放池