неподдерживаемый NSSortDescriptor (блоки сравнения не поддерживаются)

В fetchedResultsController при установке NSSortDescriptor я получаю эту ошибку unsupported NSSortDescriptor (блоки сравнения не поддерживаются).

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
                               entityForName:@"Alarm" inManagedObjectContext: managedObjectContext];
[fetchRequest setEntity:entity];

//Below code is not working and causing error. sorting use the hours&seconds part of the time attribute  

NSSortDescriptor *sort = [[NSSortDescriptor alloc]
                          initWithKey:@"time" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {

                                  NSCalendar *calendar = [NSCalendar currentCalendar];
                                  NSDateComponents *components1 = [calendar components:(NSHourCalendarUnit|NSMinuteCalendarUnit) fromDate:obj1];
                                  NSDateComponents *components2 = [calendar components:(NSHourCalendarUnit|NSMinuteCalendarUnit) fromDate:obj2];
                                  NSDate *date1 = [calendar dateFromComponents:components1];
                                  NSDate *date2 = [calendar dateFromComponents:components2];


                                  return [date1 compare:date2];

                          }];

person Anil Varghese    schedule 18.02.2013    source источник


Ответы (2)


Вы не можете использовать дескрипторы сортировки с блоками компаратора везде — например, не с выборкой основных данных.

Однако они отлично работают, когда вы фильтруете обычные массивы.

Кроме того, был ли там вопрос, который я упустил из виду?

person Monolo    schedule 18.02.2013
comment
Что я могу сделать для получения вышеуказанного результата? - person Anil Varghese; 18.02.2013
comment
@Anil Ну, простым способом может быть извлечение всех ваших данных в массив, а затем сортировка этого массива с помощью дескриптора сортировки из вашего кода. - person Monolo; 18.02.2013
comment
Мне это понравилось. Внешняя сортировка после выборки. Но проблема в том, что я использую controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath для обновления представления таблицы. При выполнении удаления какая-то другая строка в indexpath удаляется. - person Anil Varghese; 18.02.2013
comment
Я думаю, что, возможно, упущенная из виду часть заключается в том, почему бессмысленное решение (со стороны Apple) не позволять блокам компаратора работать с выборкой Core Data в первую очередь. А также как обойти это при выборке Core Data. - person aroth; 15.10.2015

Как сказал Моноло, вы не можете использовать блок компараторов с Core Data. Однако вы можете использовать:

[NSSortDescriptor sortDescriptorWithKey:(NSString *) ascending:(BOOL) selector:(SEL)]

Вам нужно будет расширить свою модель, если вы не используете стандартный селектор.

Например, мне просто нужно было упорядочить строки "а-ля Finder" (т.е. 1,2,9,10, а не 1,10,2,9) и я использовал

request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:myEntity ascending:NO selector:@selector(localizedStandardCompare:)]];

Взгляните на Справочник класса NSSortDescriptor от Apple

Удачного кодирования :)

person Bruno Belotti    schedule 14.07.2014
comment
это не работает в Core Data. Сортировка происходит в бэкэнде SQLite. localizedStandardCompare работает, вероятно, потому, что это селектор NSString, и Apple сделала что-то, чтобы перевести то, как он сравнивается. - person Zitao Xiong; 03.07.2015
comment
Извините, я не понимаю вашего комментария: я начал свой ответ с того, что вы не можете использовать блок компараторов с Core Data, я думаю, совершенно очевидно, что он не работает в Core Data... - person Bruno Belotti; 03.07.2015
comment
Я имею в виду, что селектор также не работает с основными данными. например, если у нас есть @selector(fancyCompare:) на модели. Это не работает с Core Data. - person Zitao Xiong; 04.07.2015
comment
Я не знаю о других селекторах, но могу заверить вас, что @selector(localizedStandardCompare:) работает: я использую его в TableViewController, применяя его к NSFetchRequest, как показано в моем ответе (в iOS7 и iOS8, как минимум). - person Bruno Belotti; 05.07.2015
comment
да, я реализовал свой собственный - (NSComparisonResult)typeCompare:(NSString*)obj2, но я получаю неподдерживаемый селектор NSSortDescriptor: typeCompare: в основных данных - person Zsolt; 22.07.2015
comment
Выкапывая этого зомби, так как я нашел комментарии бесполезными - вы должны использовать один из встроенных селекторов компаратора. См. stackoverflow.com/a/27972020/2200576. - person spongessuck; 23.06.2016
comment
+1 — просматривал блоки, чтобы исправить проблему с сортировкой [1, 10, 2]. Вместо этого работает localizedStandardCompare:! - person pkamb; 22.07.2016