Objective c 如何高效地获取托管对象&;按键属性作为字典索引?

Objective c 如何高效地获取托管对象&;按键属性作为字典索引?,objective-c,core-data,nsfetchrequest,Objective C,Core Data,Nsfetchrequest,所以,我有一个应用程序,我正在从web服务导入一些数据,并更新我的本地模型以匹配。web服务中的实体具有唯一标识属性,我正在使用该属性来确定是创建新的本地对象,还是获取并更新现有对象 我知道我不想循环输入并运行NSFetchRequest搜索每个项目的唯一ID的匹配项,因为fetch请求很昂贵。相反,我聚合了输入中的所有uniqueid(使用-[NSArray valueForKey:)并使用IN谓词获取所有可能存在的对象 然后,我循环输入——对于每个项目,我检查我刚才做的获取是否包含具有匹配唯

所以,我有一个应用程序,我正在从web服务导入一些数据,并更新我的本地模型以匹配。web服务中的实体具有唯一标识属性,我正在使用该属性来确定是创建新的本地对象,还是获取并更新现有对象

我知道我不想循环输入并运行
NSFetchRequest
搜索每个项目的唯一ID的匹配项,因为fetch请求很昂贵。相反,我聚合了输入中的所有uniqueid(使用
-[NSArray valueForKey:
)并使用IN谓词获取所有可能存在的对象

然后,我循环输入——对于每个项目,我检查我刚才做的获取是否包含具有匹配唯一ID的对象。如果包含,我用输入中的新值更新该对象;否则,我将创建一个新对象

我不知道如何有效地进行匹配。fetch请求为我获取一个数组,因此我需要搜索它以找到与当前输入项的uniqueID匹配的对象。现在我正在使用
-[NSArray filteredarrayingpredicate:
。。。因此,我为每个导入的项再次搜索数组(查找我知道在其中的对象)

更简洁有效的方法似乎是将获取请求结果作为字典,使用唯一ID(即在谓词中搜索的属性)作为键,相应的NSManagedObjects作为值。我可以从结果数组设置这样一个字典,但这也需要重复搜索结果数组


如果工具箱里有这样的东西,我还没找到。任何人都能找到一个好方法吗?

好的,您可以使用NSDictionary而不是uniqueID作为键值

裸骨起点可能如下所示:

NSArray *remoteObjects = // Array of dictionaries sorted by remotePrimarKey
NSArray *localObjects  = // Sorted by remotePrimaryKey using [NSPredicate predicateWithFormat:@"%@", remoteKeys];

NSInteger localIndex  = 0;
NSInteger localCount  = [localObjects count];

MyManagedObject *localObject;

for (NSDictionary *remoteObject in remoteObjects) {

  localObject = nil;

  if (localIndex < localCount) {
    localObject = [localObjects objectAtIndex:localIndex];
  }

  if (<# localObject.primaryKey == remoteObject.primaryKey #>) {
    localIndex++;
  } else {
    localObject = // create new instance of MyManagedObject
  }

  // Configure localObject here
}
NSArray*remoteObjects=//按remotePrimarKey排序的字典数组
NSArray*localObjects=//使用[NSPredicate predicateWithFormat:@“%@”,remoteKeys]按remotePrimaryKey排序;
NSInteger localIndex=0;
NSInteger localCount=[localObjects count];
MyManagedObject*本地对象;
for(远程对象中的NSDictionary*远程对象){
localObject=nil;
如果(localIndex
有很多东西你可以改变和优化,但这是我能在浏览器中写的最清楚的了

用通俗易懂的英语

设置

  • 获取按remotePrimaryKey排序并限制为远程数组中的键的本地对象
  • 确保远程数组按相同的remotePrimaryKey排序
过程

  • 一次通过一个对象单步执行远程阵列
    • 如果有一个本地对象,那么
      • 递增本地数组的索引变量
      • 配置此本地返回的对象
    • 如果没有找到本地对象
      • 创建一个新对象
      • 配置这个新的本地对象

    • 好吧,我现在觉得自己很笨。我太专注于使用我已经拥有(并在我的获取请求中使用)的uniqueid数组,以至于我忘记了我可以向后工作

      因此,以下是总体概述:

    • 读入远程对象(字典数组)

    • 从中提取一个uniqueid数组(使用
      valueForKey:
      作为从每个字典的
      objectForKey:
      循环并填充数组的缩写)

    • 使用所述数组和IN谓词获取可能存在的本地对象

    • 通过在结果数组上使用
      valueForKey:
      获取与获取结果相对应的uniqueid数组

    • 使用
      +[NSDictionary dictionary WithObjects:forKeys://code>获取将UniqueID映射到本地NSManagedObjects的字典

    • 循环访问远程对象,查询该字典以确定每个对象是否有需要更新的相应本地对象,或者我们需要为其创建新的本地对象

    • 在(简化)代码中:

      NSArray *remoteObjects; // array of dictionaries read in from server
      NSArray *remoteIDs = [remoteObjects valueForKey:@"uniqueID"];
      NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:myEntityName];
      request.predicate = [NSPredicate predicateWithFormat:@"uniqueID IN %@", remoteIDs];
      NSArray *results = [context executeFetchRequest:request error:NULL];
      NSArray *existingIDs = [results valueForKey:@"uniqueID"];
      NSDictionary *existingObjects = [NSDictionary dictionaryWithObjects:results forKeys:existingIDs];
      for (NSDictionary *remoteObject in remoteObjects) {
          MyManagedObject *existingObject = [existingObjects objectForKey:[remoteObject valueForKey:@"uniqueID"]];
          if (existingObject) {
              // have matching local object already, update it
          } else {
              // create new local object
          }
      }