根据Apple的文档(link) -
在许多情况下,您可能需要查找现有对象 (已存储在商店中的对象)用于一组离散输入值。 一个简单的解决方案是创建一个循环,然后依次为每个值 执行提取以确定是否存在匹配的持久性 对象等。这种模式不能很好地扩展。如果你个人资料 使用此模式的应用程序,您通常会找到fetch 循环中较昂贵的操作之一(与之相比) 迭代一组项目)。更糟糕的是,这种模式转变了
O(n)
问题导致O(n^2)
问题。在可能的情况下,更有效地创建所有托管 单个传递中的对象,然后修复一个中的任何关系 第二关。例如,如果导入您不知道的数据 包含任何重复项(例如,因为您的初始数据集为空), 您可以创建托管对象来表示您的数据,而不是 任何搜索都没有。或者,如果您导入“平面”数据,则无 关系,您可以为整个集创建托管对象 使用单个大
IN
保存之前清除(删除)任何重复项 谓词。
问题1:考虑到我导入的数据没有任何关系,我该如何实现最后一行中描述的内容。
如果您确实需要遵循查找或创建模式 - 请说明因为您 导入关系信息混合的异构数据 使用属性信息 - 您可以优化查找现有信息的方式 通过将执行的提取次数减少到最少来对象。 如何实现这一点取决于您的参考数据量 必须与之合作。如果要导入100个潜在的新对象,和 在您的数据库中只有2000,获取所有现有的和 缓存它们可能并不代表重大的惩罚(特别是如果 你必须多次执行操作)。但是,如果你 您的数据库中有100,000个项目,保持内存压力 那些缓存可能会让人望而却步。
您可以使用IN谓词和排序的组合来减少 您将Core Data用于单个提取请求。
示例代码:
// Get the names to parse in sorted order.
NSArray *employeeIDs = [[listOfIDsAsString componentsSeparatedByString:@"\n"]
sortedArrayUsingSelector: @selector(compare:)];
// create the fetch request to get all Employees matching the IDs
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:
[NSEntityDescription entityForName:@"Employee" inManagedObjectContext:aMOC]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(employeeID IN %@)", employeeIDs]];
// Make sure the results are sorted as well.
[fetchRequest setSortDescriptors:
@[ [[NSSortDescriptor alloc] initWithKey: @"employeeID" ascending:YES] ]];
// Execute the fetch.
NSError *error;
NSArray *employeesMatchingNames = [aMOC executeFetchRequest:fetchRequest error:&error];
最终得到两个已排序的数组 - 一个传递了员工ID 到获取请求,以及与匹配的托管对象之一 他们。要处理它们,您可以按照这些列表查看已排序的列表 步骤进行:
获取下一个ID和员工。如果ID与员工ID不匹配, 为该ID创建一个新的Employee。获取下一个员工:如果是ID 匹配,移动到下一个ID和员工。
问题2:在上面的例子中,我得到了两个排序数组,如上所述。考虑到最坏的情况,即所有要插入的对象都存在于商店中,我无论如何都看不到我可以在O(n)
时间内解决问题。 Apple描述了上述两个步骤,但这是一个O(n^2)
工作。对于输入数组中的任何kth
元素,可能存在或可能不存在与输出数组中的第一个k
元素匹配的元素。因此,在最坏的情况下,复杂性将为O(nC2) = O(n^2)
。
所以,我认为Apple正在做的是确保即使需要进行O(n^2)
检查,只获取一次进程。如果是这样,那么我会选择这个;但是有没有其他方法可以有效地做到这一点。
请理解,我不想一次又一次地获取 - 为一个大小为100的标识符的输入数组获取一次。
答案 0 :(得分:3)
广告。 1 在这里建立关系的事实并不重要。此解释仅说明如果您从例如远程服务器和您的项目有一些ID,然后您可以在一个请求中从持久性存储中获取所有ID,而不是在单独的请求中获取每个对象。
广告。 2
Apple描述了上述两个步骤,但这是一个O(n ^ 2)工作。
不是。请仔细阅读以下几行:
要处理它们,请按照以下步骤操作已排序的列表:
获取下一个ID和员工。如果ID与员工ID不匹配, 为该ID创建一个新的Employee。获取下一个员工:如果是ID 匹配,移动到下一个ID和员工。
您同时遍历数组/列表,因此您无需进行此检查:“可能存在或可能不存在与输出数组中的前k个元素匹配的元素。”您不需要检查以前的元素,因为它们已经排序,它们肯定不会包含您感兴趣的对象。
答案 1 :(得分:0)