Как я могу изменить порядок разделов с помощью NSFetchedResultsController?

Я настраиваю NSFetchRequest со следующим дескриптором сортировки:

[sortDescriptors addObject:[NSSortDescriptor sortDescriptorWithKey:@"color" ascending:YES]];

Я устанавливаю sectionNameKeyPath для NSFetchedResultsController как атрибут «цвет».

Как и следовало ожидать, результаты отсортированы по разделам по цвету.

Допустимо, чтобы атрибут "цвет" был пустой строкой "" для некоторых объектов. Все они сгруппированы в первом разделе, так как они сортируются раньше всех остальных имен. Однако я бы хотел, чтобы они отображались в качестве последнего раздела, а не первого раздела, не влияя на порядок поиска остальных объектов.

Например, в настоящее время разделы могут быть:

 ""
 "green"
 "red"
 "yellow"

Но хотелось бы, чтобы разделы были в таком порядке:

 "green"
 "red"
 "yellow"
 ""

Есть ли способ написать дескриптор сортировки, чтобы получить такое поведение? Сам я ничего не смог придумать.


person user2592842    schedule 17.07.2013    source источник


Ответы (1)


Дескриптор сортировки для запроса выборки Core Data (на основе SQLite) может использовать только некоторые стандартные методы компаратора и только (постоянные) атрибуты, хранящиеся в базе данных. Чтобы получить нестандартный порядок, вам нужно будет добавить к сущности дополнительный атрибут и использовать его для сортировки.

person Martin R    schedule 17.07.2013
comment
и этим дополнительным атрибутом может быть BOOL hasValidColor, который изменяется в перезаписанном сеттере, который устанавливает атрибут цвета. Затем вы должны отсортировать по hasValidColor и цвету. - person Matthias Bauch; 18.07.2013
comment
@MatthiasBauch: Я не уверен, можно ли использовать два дескриптора сортировки для sectionNameKeyPath. В документации сказано, что sectionNameKeyPath должен генерировать тот же порядок, что и дескриптор сортировки first. Поэтому я подумал об атрибуте xcolor, который представляет собой некоторую большую строку, если цвет пуст, и равный цвету в противном случае. - person Martin R; 18.07.2013
comment
Вы конечно правы. Я совсем забыл о секционировании. - person Matthias Bauch; 18.07.2013
comment
Некоторые дополнительные мысли. - person user2592842; 18.07.2013
comment
1. Возможно ли иметь два уровня сортировки по одному и тому же атрибуту? Что-то вроде: ‹сортировка по цвету по возрастанию›. ‹Сортировать по цвету! =› Это потребует стабильной сортировки, которая, я не уверен, гарантируется Core Data. И это потребовало бы возможности написать предикат для цвета! =, Чего я не мог понять. - person user2592842; 18.07.2013
comment
2. Еще одна мысль, которая у меня возникла, заключалась в том, чтобы оставить полученные результаты как есть. Затем внутри objectAtIndexPath, titleForSection и связанных функций я могу вернуть результаты для (section + 1)% numberOfSections. Внутренне ничего не изменилось. Но для вызывающего абонента это сделает первый раздел последним. Это может быть сложно исправить. А хитрость почти всегда проблематична. - person user2592842; 18.07.2013
comment
3. Я мог скопировать полученные результаты в массив NSArray, переместив первый раздел в последний. Это, пожалуй, самый гибкий вариант, так как я могу перемещать любые разделы по своему усмотрению. Но элегантно это не так. - person user2592842; 18.07.2013
comment
@ user2592842: 1) У вас может быть несколько уровней сортировки, но нет для ключа раздела (см. мой ответ Маттиасу выше). - 2) Я думаю, что это должно быть возможно, но очень сложно. И методы источника данных табличного представления, и методы делегата FRC должны сопоставляться между разделом табличного представления и разделом FRC. - 3) Конечно, это возможно. Единственным недостатком является то, что таблица больше не обновляется автоматически при вставке / удалении / изменении объектов. - Надеюсь, это поможет! - person Martin R; 18.07.2013
comment
Я полагаю, что Core Data напрямую не поддерживает ответ - попробуйте сами. Хех. Возможно, мне просто нужно установить инициализатор по умолчанию для поля сортировки на 0xff (или что-то вроде его эквивалента в UTF-8) вместо. Фу. В любом случае спасибо за помощь. Теперь я лучше знаю, каковы некоторые компромиссы для различных вариантов, которые у меня есть. (Конечно, если позже вы подумаете о чем-нибудь другом, дайте мне знать.) - person user2592842; 18.07.2013
comment
По связанному с этим вопросу, что касается №1 (см. Выше), мне интересно, действительно ли Core Data заботится о том, сколько уровней сортировки выполняется по ключу раздела. Пока таблица, возвращаемая из запроса SQL, находится в правильном порядке для группировки, я думаю, Core Data не заботится, как вы туда попали. Хотя просто догадываюсь. - person user2592842; 18.07.2013
comment
@ user2592842: Я использовал U + E000 в аналогичной проблеме (stackoverflow.com/a/12940825/1187415), потому что международный символ ä, €, ø может иметь Юникоды ›0xFF. - Я никогда не пробовал использовать более одного дескриптора сортировки для ключа раздела. В документации указано, что первый дескриптор сортировки в массиве используется для группировки объектов по разделам. - person Martin R; 18.07.2013
comment
@ user2592842: Пожалуйста, дайте мне знать, если вам понадобится дополнительная информация. В противном случае обратите внимание, что вы можете принять ответ, который помог, нажав на галочку. - person Martin R; 19.07.2013
comment
Немного поигравшись, я решил выбрать №2. Спасибо за помощь в этом. - person user2592842; 20.07.2013