Objective c 排序和筛选核心数据关系的更有效方法是什么?

Objective c 排序和筛选核心数据关系的更有效方法是什么?,objective-c,ios,core-data,nspredicate,nsfetchrequest,Objective C,Ios,Core Data,Nspredicate,Nsfetchrequest,假设我有一个播客实体,它有很多集,我不知道哪一个是筛选和排序的首选选项: // Always work with the relationship property - (NSSet*)unfinishedEpisodes { NSArray* episodes = self.episodes.allObjects; NSPredicate* predicate = [NSPredicate predicateWithBlock:^BOOL(PodcastEpisode* episod

假设我有一个播客实体,它有很多集,我不知道哪一个是筛选和排序的首选选项:

// 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];
}

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


谢谢。

第一个代码在处理大型结果集时效率低下,因为它在内存对象上运行。所有对象都必须加载到内存中,因此如果它们还不在内存中,则会在引发故障时逐个加载它们


第二段代码将在sql端执行所有操作,并提供已经过滤和排序的结果。CoreData还使用内部缓存来优化此类查询,因此如果剧集尚未加载到其他地方,我更希望使用此选项。启用CoreData调试以查看sql查询的外观

+1。选择2几乎肯定是最好的办法。您还可以对结果应用批处理,并可能使用
NSFetchedResultsController
来管理播客的任何显示。目前我选择的播放机中大约有1000多个未播放的播客,所以除非你知道你总是在处理小数量的播客,否则选择2是最好的。好的,现在来扩展一下。假设我有一个所有未完成剧集的桌面视图,按年龄排序,按播客分组。在这种情况下,假设您正在对照[thePodcast UnfinishedPisodesSortedBage]检查每个部分中的单元格,那么每次调用都进行核心数据提取会更好吗?或者,如果[插曲Allonfinishedepisodes]只加载一次(隐式或显式),并且只在代码中过滤接收者的插曲会更好吗?@farski在UITableView中,您肯定应该使用NSFetchedResultController,因此您需要使用NSPredicate过滤记录。与NSFetchedResultController一起使用的UITableView将使用批处理查询(
setBatchSize:
),应用程序将更高效,并消耗更少的内存。在TableView中使用节时,请记住不要使用动态属性(节应预先存储在核心数据中)。
// 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 ]];
}