我正在创建一个应用程序来解析来自xml的提要并使用Core Data存储它们。 我目前处理的问题是重复的条目。我正在解析的每个feed都包含一个唯一的id,这是我作为int在模型中得到的东西。现在我需要的是告诉核心数据不存储该实体,如果已存在具有相同ID的另一个实体。
举个例子,假设我的模型具有以下属性:
Story.id (int) - primary key
Story.title (NSString)
Story.date (NSDate)
实施该方法的最佳方法是什么?
我的方法是保留数据库中所有可用ID的记录(数组),并在插入任何内容之前,检查它是否存在。这可能适用于我的应用程序的大小,但我觉得这不是正确的方法。
答案 0 :(得分:8)
我看到两种方法。在我看来,后者(你提出的方法)是更好的解决方案。
我将id更改为primaryKey,因为我不认为在Object-C中使用id作为变量或方法名称是个好主意,因为它是一个关键字。我可能会工作,我从来没有真正尝试过。我还假设primaryKey是一个NSNumber,因为这将是如何存储在Core Data中的。
方法一每次都会对上下文执行一次获取请求:
for (id data in someSetOfDataToImport) {
NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Story" inManagedObjectContext:context]];
[request setPredicate:[NSPredicate predicateWithFormat:@"primaryKey = %d", primaryKey]];
NSUInteger count = [context countForFetchRequest:request error:nil];
[request release];
if (count > 0)
continue;
// Insert data in Managed Object Context
}
方法二做你提出的建议,将密钥缓存在一个数组中并检查它而不是去源:
NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Story" inManagedObjectContext:context]];
NSArray * allStories = [context countForFetchRequest:request error:nil];
[request release];
NSMutableArray * allPrimaryKeys = [[allStories valueForKeyPath:@"@distinctUnionOfObjects.primaryKey"] mutableCopy];
for (id data in someSetOfDataToImport) {
if ([allPrimaryKeys containsObject:data.primaryKey])
continue;
[allPrimaryKeys addObject:data.primaryKey];
// Insert data in Managed Object Context
}
[allPrimaryKeys release];
答案 1 :(得分:3)
我会警告你不要过早优化。它是所有编程邪恶的根源,浪费时间。
坦率地说,在iPhone上,你几乎不可能得到如此巨大的物体图,你开始注意到它会让事情陷入困境。我无法想象你每秒都在处理数百个独特的xml提要。
除非您同时处理数十万个主键,否则谓词方法将花费大量时间和资源,同时最大限度地降低复杂性,维护和编程时间。这是最简单,最快捷的解决方案,因此只有在您以后确定其瓶颈时才能使用它来启动然后进行优化。