排序和过滤核心数据关系的更有效方法是什么?

时间:2013-01-07 05:16:22

标签: objective-c ios core-data nspredicate nsfetchrequest

假设我有一个Podcast实体,它有很多剧集,我很困惑这些将是剔除和排序的首选选项:

// Always work with the relationship property
- (NSSet*)unfinishedEpisodes {
  NSArray* episodes = self.episodes.allObjects;

  NSPredicate* predicate = [NSPredicate predicateWithBlock:^BOOL(PodcastEpisode* episode, NSDictionary* bindings) {
    return !episode.isFinished;
  }];

  NSArray* unfinishedEpisodes = [episodes filteredArrayUsingPredicate:predicate];

  return [NSSet setWithArray:unfinishedEpisodes];
}

- (NSArray*)unfinishedEpisodesSortedByAge {
  NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES];

  return [self.unfinishedEpisodes.allObjects sortedArrayUsingDescriptors:sortDescriptors];
}

// Fetch specific sets of data as needed
- (NSArray*)unfinishedEpisodes:(NSArray*)sortDescriptors {  
  NSFetchRequest* fetch = [[NSFetchRequest alloc] initWithEntityName:@"Episode"];

  NSPredicate* predicate = [NSPredicate predicateWithFormat:@"podcast == %@ AND playcount == 0", self];
  fetch.predicate = predicate;

  fetch.sortDescriptors = sortDescriptors;

  NSArray* results = [KRTDataManager.sharedManager.mainObjectContext executeFetchRequest:fetch error:nil];

  return results;
}

- (NSArray*)unfinishedEpisodesSortedByAge {
  NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES];

  return [self unfinishedEpisodes:@[ sortDescriptor ]];
}

我在SQL中尽可能多地做的部分很难认为选项1更好,但我读过的大部分内容似乎表明使用(NSSet *)剧集一旦播客非常便宜对象出现了。我对在这些情况下如何处理核心数据错误的理解非常不稳定,我意识到核心数据不应该真正与SQL数据库进行比较。但是,简单地根据两个选项的构造方式,我认为将谓词和sortdescriptors直接加到fetch中有一些好处;但也许这还不足以弥补关系所带来的收益。

感谢。

1 个答案:

答案 0 :(得分:2)

使用大型结果集时,第一个代码效率低,因为它在内存对象中运行。所有对象都必须加载到内存中,因此如果它们尚未存在,则会在出现故障时逐个加载

第二个代码将在sql端执行所有操作,并为您提供已过滤和排序的结果。 CoreData还使用内部缓存来优化此类查询,因此如果剧集尚未在其他地方加载,我会更喜欢此选项。启用CoreData调试以查看sql查询的外观。 There is already an answer how to do that