我正在运行Instruments以在我的iPhone应用程序中找到memoryleaks。
正如您在下面的屏幕截图中看到的,我从一些Foundation对象中获得了一些奇怪的内存泄漏。
如果我理解的话,那些最让我烦恼的是应该“自动”释放的那个。如:NSPredicate predicateWithFormat,NSKeyedUnarchiver unarchiveObjectWithData等......
这里有一个屏幕截图,其中包含NSPredicate的更多信息:
请你帮我理解我做错了什么?
在代码中我只是这样做:
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];
所以我不应该释放谓词吧?无论如何,我试过,它让我的代码崩溃......
提前感谢您的帮助!
答案 0 :(得分:1)
保留/释放模型与(例如)malloc / free不同。仅使用版本平衡对象创建或使用返回自动释放对象的方法是不够的。对象上的每个retain
必须与release
平衡。如果您只错过一个,则对象会泄露。 Instruments指出了对象的创建位置,但没有指出泄漏的位置。 Instruments指出每个保留,但不会(也不能)指出哪个保留未正确平衡。
您没有指定实际泄漏的内容,因此我必须根据您的代码提供一个通用示例。
我们假设basePredicate
正在泄漏:
basePredicate
中为其他对象分配了所有权(即调用retain
)。该对象没有释放它。basePredicate
中为其他对象分配了所有权,如上所述,但该对象会释放它。对象可能会将basePredicate
移到某个声明对其拥有所有权的其他对象上。如果这听起来很可怕,那就有点儿了。但修复实际上很简单:确保每次代码声明对retain
对象的所有权(或对具有保留的属性赋值)时,它都有相应的 yield <所有权的/ em>,以release
或autorelease
的形式(或对财产的分配为零)。
过去,当我发现泄漏时,我找不到,我发现最好的办法是研究哪些物体泄漏并确定它们之间的关系(如果有的话)。然后我浏览我的代码并查找我尚未发布的对象。
此外,如果您还没有,请开始使用静态分析仪。它找不到像这样的所有问题,但是当找到它时你会节省很多时间。