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

Posted

技术标签:

【中文标题】是否有更快的方法来检查是否存在数千个 NSManagedObject 项目?【英文标题】:Is there a faster way to check if thousands of NSManagedObject items exist? 【发布时间】:2011-12-07 15:15:30 【问题描述】:

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

我正在从 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;
  

【问题讨论】:

【参考方案1】:

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

【讨论】:

谢谢。这几乎正​​是我想要的。【参考方案2】:

可以加快此代码速度(以消耗一些内存为代价)的一件事是将 所有 潜在匹配项从您的数据存储中提取到一个集合或数组中并查询该集合以查看是否具有您的目标 ID 的对象在其中。 Core Data 中的获取请求比针对一组对象的等效查询慢很多

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

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

【讨论】:

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

以上是关于是否有更快的方法来检查是否存在数千个 NSManagedObject 项目?的主要内容,如果未能解决你的问题,请参考以下文章

可读取的套接字数据

有没有更快的方法来检查 LINQ to XML 中的 XML 元素?

可以使用C预处理器来判断文件是否存在吗?

在Web应用程序部署过程中将数千个文件部署到FTP

测试RspecCapybara中的页面是否不存在链接?

以编程方式批量添加数千个 Android 联系人