【问题标题】:How to prevent Core Data making duplicates in iOS 5?如何防止 Core Data 在 iOS 5 中重复?
【发布时间】:2012-03-11 15:27:42
【问题描述】:

我遇到了问题。

周末我一直在做一个项目,我从网络服务中提取一个大的 xml。

它基本上有 3 层 - 客户、经理、员工,都是分层的。因此,应用程序第一次运行时,它会提取此 xml 并对其进行解析并在 3 个相关实体(客户、经理和员工)中创建所有条目。

每次应用程序启动时,我都需要删除相同的 XML,但这一次,我只需要“更新”任何已更改的现有记录,或为新客户、经理或员工添加新记录自上次以来出现过。

所以,正如我所说,目前它正在提取所有内容,正确解析并创建正确的实体并填充所有属性。

但是,在没有数据更改的情况下,在第 2 次启动时,它会复制所有数据 - 所以我有 30 个客户而不是 15 个客户(正确的数字)等等......

我真的必须在解析中添加大量代码来检查它是否已经存在,而不是创建一个新的 NSManagedObject 吗?

如果是 - 我必须手动检查每个属性?

这非常痛苦和冗长 - 有没有办法让 Core Data 自动为我做这种事情?

感谢您的任何帮助或建议。

【问题讨论】:

    标签: ios web-services core-data duplicates


    【解决方案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;
        }
    }
    

    【讨论】:

    • 为什么获取结果的可变复制?
    猜你喜欢
    • 1970-01-01
    • 2011-03-12
    • 2011-03-05
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-12
    相关资源
    最近更新 更多