iPhone NSCFString 在 fetchRequest 中泄漏

发布于 2024-08-30 02:05:36 字数 1262 浏览 7 评论 0原文

在以下代码中:

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

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

我知道泄密对于 iPhone 开发者来说是很严重的……但我不知道如何堵住这个漏洞。

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

多谢!

In the following code:

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

... I Fetch notes for a given categoryName. When I'm running Instruments, it says that a NSCFString is leaking.

I know leaks are mean for iPhone developers... but I don't have any idea on how to plug this one.

Any clues? All help is welcome.

Thanks a lot!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

御守 2024-09-06 02:05:36

您的问题是这样的:

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

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

请改用 return [result autorelease];

Your problem is this:

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

mutableCopy returns an owning reference (ie, an object with a +1 retain count), which you are responsible for (auto)releasing. You don't, and you then relinquish the reference, which means you've leaked the array.

Use return [result autorelease]; instead.

阳光①夏 2024-09-06 02:05:36

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

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

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

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

First of all, Instruments may not be always accurate.
It can report leaks on some special case, just because it don't see you are actually releasing the object elsewhere.

It's also possible that some parts of the CF have leaks.

What I can see in your code is that you are using auto-released objects.
You're temporary objects will have a long life-cycle.
What append if you release them explicitly instead, just before the method's return?

You are also returning a copy of an object.
You have to make sure that object is released at some point.
It may be much better to return an auto-released object, and let the calling method decide if the object should be retained.

旧伤慢歌 2024-09-06 02:05:36

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

我认为您没有实际的泄漏,但是通过这样做:

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

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

自动释放实际上使对象的生存时间比直接释放更长,因为它会导致对象挂起,直到外部自动释放池耗尽。例如,如果您在对象 A 内创建对象 B 并将其返回给自动释放的对象 C,则在对象 A 被释放后,对象 B 仍将保持活动状态很长时间,即使对象 C 从未保留它。 (尽管它最终会在不可预测的时刻消亡。)

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

如果您这样做:

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

...您的泄漏将会消失。

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

return [result autorelease];

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

Since you don't create any strings, the leaking string is most likely one of the strings that ends up inside the fetch request and it is most likely the fetch request that is actually leaking. (The call stack shown in Instruments should confirm this.)

I don't think you have an actual leak but by doing this:

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

... you are allowing the fetchRequest to live beyond the scope where it was defined Instruments will interpret that as a leak.

Autorelease actually makes objects live longer than direct release because it causes objects to hang around until the outer autorelease pool is drained. For example, if you create object-B inside object-A and return it to object-C autoreleased, object-B will stay alive long after object-A has been deallocated even if object-C never retains it. (Although it will eventually die at an unpredictable moment.)

Autorelease is not a convenience method for retaining. It has a specific purpose of retaining objects that are being passed between other objects. If your not doing this, don't use autorelease.

If you do this:

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

... your leak will go away.

You might, however, want to do this:

return [result autorelease];

... to ensure that the result array lives long enough to be retained by another object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文