Каков более эффективный способ сортировки и фильтрации основных данных?
Предполагая, что у меня есть объект 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*) становится чрезвычайно дешевым, когда объект подкаста входит в существование. Мое понимание того, как сбои данных Core обрабатываются в этих ситуациях, довольно шатко, и я понимаю, что данные Core не следует реально сравнивать с базой данных SQL. Просто основываясь на том, как устроены эти два варианта, я думаю, что есть некоторая выгода для выпекания предиката и дескрипторов сортировки прямо в выборку; но, возможно, этого недостаточно, чтобы компенсировать выгоды, которые дают отношения, предоставляемые отношениями.
Благодарю.
1 ответ
Первый код будет неэффективным при работе с большими наборами результатов, так как он работает в объектах памяти. Все объекты должны быть загружены в память, поэтому, если их там еще нет, они будут загружаться один за другим по мере возникновения неисправностей.
Второй код будет делать все на стороне SQL и даст вам уже отфильтрованные и отсортированные результаты. CoreData также использует внутреннее кэширование для оптимизации таких запросов, поэтому я бы предпочел эту опцию, если эпизоды еще не загружены где-то еще. Включите отладку CoreData, чтобы увидеть, как будут выглядеть SQL-запросы. Уже есть ответ, как это сделать.