如何防止 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 中重复?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Core Data 和 iOS 5 存储指南?

iPhone 4 iOS 5 如何使用 Core Data 保存 MPMediaItem?

如何防止备份带有外部文件的 Core Data 数据库?

iOS 5/Lion Core Data 有序关系:指定顺序?

如何防止在Angular Js1.2中重定向<a href="#something">

Core Data - 无法在 iOS 5.1 上创建持久存储