内存泄漏自动释放对象?

时间:2011-03-17 15:33:57

标签: objective-c memory-leaks instruments autorelease

我正在运行Instruments以在我的iPhone应用程序中找到memoryleaks。

正如您在下面的屏幕截图中看到的,我从一些Foundation对象中获得了一些奇怪的内存泄漏。

Screenshot form Instruments

如果我理解的话,那些最让我烦恼的是应该“自动”释放的那个。如:NSPredicate predicateWithFormat,NSKeyedUnarchiver unarchiveObjectWithData等......

这里有一个屏幕截图,其中包含NSPredicate的更多信息: enter image description here

请你帮我理解我做错了什么?

在代码中我只是这样做:

NSPredicate *basePredicate = [NSPredicate predicateWithFormat:@"ANY fcLists IN %@", listsIds];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.context];
[self.fetchRequest setEntity:entity];

// Load the list of new items
NSPredicate *addedPredicate = [NSPredicate predicateWithFormat:@"fcStatus = -2"];
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:basePredicate, addedPredicate, nil]];
[self.fetchRequest setFetchLimit:self.nbOfNewItems];
[self.fetchRequest setPredicate:predicate];
tmp = [self.context executeFetchRequest:self.fetchRequest error:&error];

所以我不应该释放谓词吧?无论如何,我试过,它让我的代码崩溃......

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

保留/释放模型与(例如)malloc / free不同。仅使用版本平衡对象创建或使用返回自动释放对象的方法是不够的。对象上的每个retain必须与release平衡。如果您只错过一个,则对象会泄露。 Instruments指出了对象的创建位置,但没有指出泄漏的位置。 Instruments指出每个保留,但不会(也不能)指出哪个保留未正确平衡。

您没有指定实际泄漏的内容,因此我必须根据您的代码提供一个通用示例。

我们假设basePredicate正在泄漏:

  1. 对于basePredicate泄漏这个最简单的情况是你根本就没有调用它。但是,在这种情况下,您将使用返回自动释放对象的方法创建它。
  2. 下一种可能性是,您在basePredicate中为其他对象分配了所有权(即调用retain)。该对象没有释放它。
  3. 下一种可能性是,您在basePredicate中为其他对象分配了所有权,如上所述,但该对象释放它。对象可能会将basePredicate移到某个声明对其拥有所有权的其他对象上。
  4. 接下来,您拥有所有权的对象本身可能会被泄露。
  5. 最后三种情景中几乎有无数的排列。
  6. 如果这听起来很可怕,那就有点儿了。但修复实际上很简单:确保每次代码声明retain对象的所有权(或对具有保留的属性赋值)时,它都有相应的 yield <所有权的/ em>,以releaseautorelease的形式(或对财产的分配为零)。

    过去,当我发现泄漏时,我找不到,我发现最好的办法是研究哪些物体泄漏并确定它们之间的关系(如果有的话)。然后我浏览我的代码并查找我尚未发布的对象。

    此外,如果您还没有,请开始使用静态分析仪。它找不到像这样的所有问题,但是当找到它时你会节省很多时间。