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

时间:2011-12-07 15:15:30

标签: objective-c core-data nsmanagedobject nsfetchrequest

我将在这里使用Google阅读器客户端的示例,因为这就是我实际做的......

我从谷歌阅读器帐户中提取(可能有数千个)项目,我想知道是否有更快的方法来检查数据存储中是否已经有一个项目(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;
  }
}

2 个答案:

答案 0 :(得分:1)

加速此代码的一件事(以牺牲一些内存使用为代价)是将所有潜在匹配从数据存储中拉出到一个集合或数组中并查询设置以查看是否包含目标ID的对象。核心数据中的获取请求比对一组对象的等效查询慢

- (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;
}

此代码已编写到位,因此可能无法正常编写。此外,有一些聪明的方法可以加快速度,但如图所示,它应该比单个提取请求快得多。

答案 1 :(得分:1)

查看Efficiently Importing Data的Apple文档,他们有几种不同的方法可以使用代码段为不同的方案导入数据。