Objective c 是否有更快的方法检查是否存在数千个NSManagedObject项?

Objective c 是否有更快的方法检查是否存在数千个NSManagedObject项?,objective-c,core-data,nsmanagedobject,nsfetchrequest,Objective C,Core Data,Nsmanagedobject,Nsfetchrequest,我将在这里使用Google Reader客户端的示例,因为这就是我实际正在做的 我正在从Google Reader帐户中提取(可能有数千个)项目,我想知道是否有更快的方法来检查数据存储中是否已经有项目(NSManagedObject)。Google Reader为每个项目提供一个唯一的字符串ID,我将其存储在我的NSManagedObjects中。下面是我导入时所做工作的精简基础。请注意,我确实使用了背景线程,但为了清晰起见,我在这里将它们去掉了 我能更有效地做这件事吗 - (void)impo

我将在这里使用Google Reader客户端的示例,因为这就是我实际正在做的

我正在从Google Reader帐户中提取(可能有数千个)项目,我想知道是否有更快的方法来检查数据存储中是否已经有项目(NSManagedObject)。Google Reader为每个项目提供一个唯一的字符串ID,我将其存储在我的NSManagedObjects中。下面是我导入时所做工作的精简基础。请注意,我确实使用了背景线程,但为了清晰起见,我在这里将它们去掉了

我能更有效地做这件事吗

- (void)importBatchOfItems:(NSArray *)itemsFromGoogleReader isLastBatch:(BOOL)isLastBatch {
  for (NSDictionary *item in *itemsFromGoogleReader) {
    NSManagedObject *feedItem = [self feedItemWithId:[item valueForKey:@"GoogleReaderItemID"]];
    if (feedItem == nil) {
      feedItem = [self insertFeedItem];
    }

    // ... do some stuff with feedItem
  }

  BOOL saveIntervalElapsed = (([NSDate timeIntervalSinceReferenceDate] - self.lastBatchSave) >= kBatchSaveInterval);

  if (saveIntervalElapsed || isLastBatch) {
    [self saveContext];
  }
}

- (NSManagedObject *)feedItemWithId:(NSString *)itemId {
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id = %@", itemId];

  [self.uniqueItemFetchRequest setPredicate:predicate];
  NSArray *items = [self.managedObjectContext executeFetchRequest:self.uniqueItemFetchRequest error:nil];

  if ([items count] > 0) {
    return [items objectAtIndex:0];
  } else {
    return nil;
  }
}

加快这段代码速度的一件事(以牺牲一些内存使用为代价)是将所有可能的匹配项从数据存储中提取到一个集合或数组中,并查询该集合,以查看其中是否有具有目标ID的对象。核心数据中的Fetch请求比针对一组对象的等效查询慢得多

- (NSManagedObject *)feedItemWithId:(NSString *)itemId {
  NSArray *fetchedObjects; // Assume this has already been generated

   NSUInteger i = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
     if ([idx id] = itemID)            
       return YES;
     else
       return NO;
    }];

  if (i != NSNotFound)
    return [array objectAtIndex:i];
  else
    return nil;
}

此代码是就地编写的,因此可能无法按编写的方式工作。此外,当然有一些聪明的方法可以加快速度,但如图所示,它的运行速度应该比单独的获取请求快得多。

看看Apple文档,它们有几种不同的方法可以使用代码片段为不同的场景导入数据。

感谢您的建议。我可以试一试,但在一定数量的物体之后,这似乎并不有效。我很可能有5000个甚至10000个对象要检查。核心数据获取请求真的比在数组中迭代10000个对象慢吗?似乎应该在幕后进行一些优化,使提取请求更快。提取请求会更慢。对于您请求的每个请求,执行一个新的SQLite查询。I/O操作非常昂贵。我要做的是建立一个庞大的测试数据库,并尝试两种方法。在数组上迭代几乎可以保证更快,但它可能会导致内存问题。谢谢。这正是我想要的。