iPhone NSCFString在fetchRequest中泄漏

时间:2010-04-20 12:16:04

标签: iphone objective-c xcode memory-leaks nsfetchrequest

在以下代码中:

- (NSMutableArray *) fetchNotesForGroup: (NSString *)groupName {

 // Variables declaration
 NSMutableArray *result;
 NSFetchRequest *fetchRequest;
 NSEntityDescription *entity;
 NSSortDescriptor *sortDescriptor;
 NSPredicate *searchPredicate;
 NSError *error = nil;

 // Creates the fetchRequest and executes it
 fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
entity = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"noteName" ascending:YES] autorelease];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[fetchRequest setReturnsDistinctResults:YES];
searchPredicate = [NSPredicate predicateWithFormat:@"categoryName like %@", groupName];
[fetchRequest setPredicate:searchPredicate];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:@"noteName"]];
result = [[managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];

 // Variables release

 return result;
}

...我获取给定categoryName的注释。当我运行Instruments时,它说NSCFString正在泄漏。

我知道泄漏对iPhone开发者来说意味着......但我不知道如何插入这个泄漏。

任何线索?欢迎大家帮忙。

非常感谢!

3 个答案:

答案 0 :(得分:1)

你的问题是:

result = [[managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
// Variables release
return result;

mutableCopy返回一个拥有引用(即具有+1保留计数的对象),您负责(自动)释放。你没有,然后你放弃了引用,这意味着你已经泄漏了数组。

改为使用return [result autorelease];

答案 1 :(得分:0)

首先,仪器可能并不总是准确的 它可以报告某些特殊情况下的泄漏,只是因为它没有看到您实际上是在其他地方释放该物体。

CF的某些部分也可能有泄漏。

我在你的代码中看到的是你正在使用自动释放的对象 你是临时物品的生命周期很长 如果您在方法返回之前明确地释放它们会附加什么?

您还要返回一个对象的副本 你必须确保在某个时刻释放对象 返回自动释放的对象可能要好得多,让调用方法决定是否应保留该对象。

答案 2 :(得分:0)

由于您没有创建任何字符串,因此泄漏字符串很可能是在获取请求中结束的字符串之一,并且很可能是实际泄漏的获取请求。 (仪器中显示的调用堆栈应该确认这一点。)

我不认为你有实际的泄漏,但这样做:

 fetchRequest = [[[NSFetchRequest alloc] init] autorelease];

...你允许fetchRequest超出定义的范围,仪器会将其解释为泄漏。

自动释放实际上使对象比直接释放更长寿,因为它会导致对象挂起,直到外部自动释放池耗尽。例如,如果在object-A中创建object-B并将其返回到object-C autoreleased,则object-B将在object-A被释放后很长时间保持活动状态,即使object-C从未保留它。 (虽然最终会在不可预测的时刻死去。)

Autorelease不是保留的便捷方法。它具有保留在其他对象之间传递的对象的特定目的。如果您不这样做,请不要使用自动释放。

如果你这样做:

fetchRequest = [[NSFetchRequest alloc] init];
// ...
[fetchRequest release];

......你的泄漏会消失。

但是,您可能希望这样做:

return [result autorelease];

...确保结果数组足够长,以便被另一个对象保留。