1

在以下代码中:

- (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;
}

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

我知道泄漏对 iPhone 开发人员来说意味着什么……但我不知道如何解决这个问题。

有什么线索吗?欢迎所有帮助。

非常感谢!

4

3 回答 3

1

你的问题是这样的:

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

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

改为使用return [result autorelease];

于 2010-04-20T13:51:43.873 回答
0

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

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

我在您的代码中可以看到您正在使用自动释放的对象。
你的临时对象会有很长的生命周期。
如果您在方法返回之前显式释放它们,会追加什么?

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

于 2010-04-20T12:38:53.493 回答
0

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

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

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

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

与直接释放相比,自动释放实际上使对象的寿命更长,因为它会导致对象一直徘徊,直到外部自动释放池被耗尽。例如,如果您在对象-A 内创建对象-B 并将其返回给对象-C 自动释放,则对象-B 将在对象-A 被释放后很长时间保持活动状态,即使对象-C 从未保留它。(尽管它最终会在不可预知的时刻死去。)

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

如果你这样做:

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

...您的泄漏将消失。

但是,您可能想要这样做:

return [result autorelease];

...以确保结果数组的寿命足以被另一个对象保留。

于 2010-04-20T12:41:13.797 回答