如何防止 Core Data 在 iOS 5 中重复?
Posted
技术标签:
【中文标题】如何防止 Core Data 在 iOS 5 中重复?【英文标题】:How to prevent Core Data making duplicates in iOS 5? 【发布时间】:2012-03-11 15:27:42 【问题描述】:我遇到了问题。
周末我一直在做一个项目,我从网络服务中提取一个大的 xml。
它基本上有 3 层 - 客户、经理、员工,都是分层的。因此,应用程序第一次运行时,它会提取此 xml 并对其进行解析并在 3 个相关实体(客户、经理和员工)中创建所有条目。
每次应用程序启动时,我都需要删除相同的 XML,但这一次,我只需要“更新”任何已更改的现有记录,或为新客户、经理或员工添加新记录自上次以来出现过。
所以,正如我所说,目前它正在提取所有内容,正确解析并创建正确的实体并填充所有属性。
但是,在没有数据更改的情况下,在第 2 次启动时,它会复制所有数据 - 所以我有 30 个客户而不是 15 个客户(正确的数字)等等......
我真的必须在解析中添加大量代码来检查它是否已经存在,而不是创建一个新的 NSManagedObject 吗?
如果是 - 我必须手动检查每个属性?
这非常痛苦和冗长 - 有没有办法让 Core Data 自动为我做这种事情?
感谢您的任何帮助或建议。
【问题讨论】:
【参考方案1】:我担心您必须自己保持数据库清洁......最简单的方法是使用NSFetchRequest
:导入更新的数据时,您可以对现有数据运行查询并决定要做什么。
正如 Marcus S. Zarra 在another thread 中提到的那样:
当您导入新行时,您可以针对 现有的行,看看它是否已经到位。为此,您创建 针对您的实体的 NSFetchRequest,设置要查找的谓词 guid 属性并将返回的最大行数设置为 1。
我建议您在 导入,以便您在导入时可以重用它。如果 NSFetchRequest 返回一行,您可以更新该行。如果没有 返回一行然后你可以插入一个新行。
正确完成后,您会发现性能超过 可以接受。
另一个很好的信息来源是 Apples Programming Guides:Core Data Programming Guide
【讨论】:
@iosProgrammingIsFun 如果我的帖子对您有帮助,您可以接受 :) @Besi:谢谢!我已经修复了网址。【参考方案2】:如 Apple Docs https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html 中所述
您需要循环数据模型并像这样从那里处理它
例子:
// loop over employeeIDs
// anID = ... each employeeID in turn
// within body of loop
NSString *predicateString = [NSString stringWithFormat: @"employeeID == %@", anID];
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
就我个人而言,我不喜欢这种方法,我编写了这个 sn-p 代码,它以高效的方式处理这个问题,而且很简单!我注意到使用 Apples 方法时遇到了字符串具有不同字符(例如大写字母和空格)的问题。如果您正确重命名所有相应的对象,则下面的代码已经过测试并且可以正常工作。老实说,这是实现不在核心数据中添加重复项的最有效方法。
-(void)AvoidDuplicatesinDataModel
// Define our table/entity to use
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Users"
inManagedObjectContext:managedObjectContext];
// Setup the fetch request
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
// Define how we will sort the records
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"users"
ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
// Fetch the records and handle an error
NSError *Fetcherror;
NSMutableArray *mutableFetchResults = [[managedObjectContext
executeFetchRequest:request error:&Fetcherror] mutableCopy];
if (!mutableFetchResults)
// Handle the error.
// This is a serious error
//here usersNameTextField.text can be any (id) string that you are searching for
if ([[mutableFetchResults valueForKey:@"users"]
containsObject:usernameTextField.text])
//Alert user or handle your duplicate methods from here
return;
【讨论】:
为什么获取结果的可变复制?以上是关于如何防止 Core Data 在 iOS 5 中重复?的主要内容,如果未能解决你的问题,请参考以下文章
iPhone 4 iOS 5 如何使用 Core Data 保存 MPMediaItem?
iOS 5/Lion Core Data 有序关系:指定顺序?