iPhone NSCFString 在 fetchRequest 中泄漏
在以下代码中:
- (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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的问题是这样的:
mutableCopy 返回一个拥有引用(即具有+1 保留计数的对象),您负责(自动)释放该引用。你不这样做,然后你放弃了引用,这意味着你已经泄漏了数组。
请改用
return [result autorelease];
。Your problem is this:
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.首先,仪器可能并不总是准确的。
它可以报告某些特殊情况下的泄漏,只是因为它看不到您实际上在其他地方释放了对象。
也有可能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.
由于您没有创建任何字符串,因此泄漏字符串很可能是最终出现在提取请求中的字符串之一,并且很可能是实际泄漏的提取请求。 (Instruments 中显示的调用堆栈应该证实了这一点。)
我认为您没有实际的泄漏,但是通过这样做:
...您允许 fetchRequest 超出其定义的范围,Instruments 会将其解释为泄露。
自动释放实际上使对象的生存时间比直接释放更长,因为它会导致对象挂起,直到外部自动释放池耗尽。例如,如果您在对象 A 内创建对象 B 并将其返回给自动释放的对象 C,则在对象 A 被释放后,对象 B 仍将保持活动状态很长时间,即使对象 C 从未保留它。 (尽管它最终会在不可预测的时刻消亡。)
自动释放并不是一种方便的保留方法。它具有保留在其他对象之间传递的对象的特定目的。如果您不这样做,请不要使用自动释放。
如果您这样做:
...您的泄漏将会消失。
但是,您可能想要这样做:
...以确保结果数组的寿命足够长,以便由另一个对象保留。
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:
... 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:
... your leak will go away.
You might, however, want to do this:
... to ensure that the result array lives long enough to be retained by another object.