我需要查看我的核心数据库中是否存在从具有唯一标识符的CSV文件中获取的对象,这是我认为适合此任务的代码:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity;
entity =
[NSEntityDescription entityForName:@"ICD9"
inManagedObjectContext:passedContext];
[fetchRequest setEntity:entity];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"uniqueID like %@", uniqueIdentifier];
[fetchRequest setPredicate:pred];
NSError *err;
NSArray* icd9s = [passedContext executeFetchRequest:fetchRequest error:&err];
[fetchRequest release];
if ([icd9s count] > 0) {
for (int i = 0; i < [icd9s count]; i++) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSString *name = [[icd9s objectAtIndex:i] valueForKey:@"uniqueID"];
if ([name caseInsensitiveCompare:uniqueIdentifier] == NSOrderedSame && name != nil)
{
[pool release];
return [icd9s objectAtIndex:i];
}
[pool release];
}
}
return nil;
经过更彻底的测试后,似乎这个代码导致我正在编写的应用程序中出现大量泄漏(它在3GS上崩溃,然后通过1459项目将其降低20%)。我觉得这不是最有效的方法,对于更有效的内存方式有什么建议吗?提前谢谢!
答案 0 :(得分:2)
like
运算符。使用=
。那应该快得多。[c]
修饰符通过谓词指定搜索的不区分大小写。NSAutoreleasePool
。事实上,根本不需要它。for()
循环内进行任何检查。你复制了谓词的工作。所以我会将你的代码更改为:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:...];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"uniqueID =[c] %@", uniqueIdentifier]];
NSError *err = nil;
NSArray *icd9s = [passedContext executeFetchRequest:fetchRequest error:&err];
[fetchRequest release];
if (error == nil && [icd9s count] > 0) {
return [icd9s objectAtIndex:0]; //we know the uniqueID matches, because of the predicate
}
return nil;
答案 1 :(得分:1)
使用Instruments中的Leaks模板搜寻泄漏。修复它们后,您当前的代码可能会很好。泄漏甚至可能不是代码。
其他问题:
release
发送到自动释放池。如果您将代码移植到垃圾收集的Cocoa,则池将不会执行任何操作。而是发送它drain
;在保留释放Cocoa和Cocoa Touch中,这与release
的工作方式相同,并且在垃圾收集的Cocoa中,它会占用垃圾收集器,垃圾收集器是GC-land中最接近排放池的等效物。[pool release];
行,这让每位经验丰富的Cocoa和Cocoa Touch程序员都非常担心。将测试结果存储在布尔变量中的名称上,然后在条件之前排空池,然后有条件地返回对象。-[NSArray count]
返回,-[NSArray objectAtIndex:]
需要NSUInteger
,而不是int
。尽量保持所有类型的匹配。 (切换到快速枚举当然会以不同的方式解决此问题的这个实例。)