Как отсортировать свойства исходных данных
Документация по основным данным гласит, что:
Запрос на выборку, связанный с свойством [fetched], может иметь упорядочение сортировки, и, таким образом, можно выбрать упорядоченное свойство.
Как указать дескрипторы сортировки для выбранного свойства в редакторе модели данных Xcode? Я не могу найти подходящую область где угодно. Я разрабатываю платформу для iPhone, если это имеет значение.
Если это невозможно с помощью редактора графической модели, как мне изменить модификацию запроса на выборку для выбранного свойства в коде, чтобы он имел дескриптор сортировки?
Ответы
Ответ 1
Инструмент моделирования не имеет способа установить дескрипторы сортировки в запросе выборки.
После загрузки модели должно быть возможно [1], но прежде, чем связать его с постоянным координатором хранилища, найдите описания свойств, для которых вы хотите управлять порядком сортировки, и замените их запросы на выборки с помощью запросов на выборку которые имеют дескрипторы сортировки, установленные на них.
[1] В принципе это должно сработать. На практике я этого не делал и не тестировал.
Ответ 2
Фактически вы можете захватить свойство модели и добавить к нему дескрипторы сортировки (опять же, в коде). Я сделал это в стандартном методе, который XCode генерирует в AppDelegate, если вы выберете один из шаблонов с Core Data:
Кстати. Это сортирует ВСЕ выбранные свойства для ВСЕХ моделей в вашей модели данных. Вы могли бы придумать и приспособиться к ней, но это был самый краткий способ обработки сортировки 7 отдельных моделей, каждая из которых выбрала свойства, которые нужно было отсортировать по имени. Хорошо работает.
/**
Returns the managed object model for the application.
If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
*/
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
// Find the fetched properties, and make them sorted...
for (NSEntityDescription *entity in [managedObjectModel entities]) {
for (NSPropertyDescription *property in [entity properties]) {
if ([property isKindOfClass:[NSFetchedPropertyDescription class]]) {
NSFetchedPropertyDescription *fetchedProperty = (NSFetchedPropertyDescription *)property;
NSFetchRequest *fetchRequest = [fetchedProperty fetchRequest];
// Only sort by name if the destination entity actually has a "name" field
if ([[[[fetchRequest entity] propertiesByName] allKeys] containsObject:@"name"]) {
NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]];
[sortByName release];
}
}
}
}
return managedObjectModel;
}
Ответ 3
Вы не укажете их в графическом редакторе (насколько я знаю).
Вы указываете их в коде, в котором вы делаете выборку.
NSFetchRequest* request = [[NSFetchRequest alloc] init];
NSEntityDescription* entity = [NSEntityDescription entityForName:@"whatYouAreLookingFor"
inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
// here where you specify the sort
NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"name" ascending:YES];
NSArray* sortDescriptors = [[[NSArray alloc] initWithObjects: sortDescriptor, nil] autorelease];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:@"myCache"];
Ответ 4
Используя отличный ответ Тиму Шаделю, я добавил сортировку подкласса по-NSManagedObject...
... в Tier.m(который является подклассом NSManagedObject)...
+ (void)initialize
{
if(self == [Tier class])
{
NSFetchedPropertyDescription *displayLessonPropertyDescription = [[[Tier entityDescription] propertiesByName] objectForKey:@"displayLesson"];
NSFetchRequest *fetchRequest = [displayLessonPropertyDescription fetchRequest];
NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"displayOrder" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]];
[sortByName release];
}
}
Ответ 5
К сожалению, способность сортировки несколько ограничена. Например, вы не можете взять поле, которое является NSString, содержащее число, и отсортировать его по численному признаку, по крайней мере, не с хранилищем резервных копий SQLite. Пока вы сортируете по алфавиту по строкам, численно только по значениям, хранящимся в виде чисел и т.д., Однако, NSSortDescriptor, примененный к запросу выборки, работает очень хорошо.
Ответ 6
Поместите это в свой подкласс NSManagedObject
:
+ (void)initialize
{
if (self != [EntityManagedObjectSubClass class]) return;
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
NSEntityDescription *entityDescription = [managedObjectModel entitiesByName][@"entityName"];
NSFetchedPropertyDescription *fetchedPropertyDescription = [entityDescription propertiesByName][@"fetchedPropertyName"];
NSFetchRequest *fetchRequest = [fetchedPropertyDescription fetchRequest];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"sortDescriptorKey" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
}
Замените EntityManagedObjectSubClass
, entityName
, fetchedPropertyName
и sortDescriptorKey
своими собственными вещами.
Ответ 7
Jeff, если строки выровнены по правому краю, вы можете просто отсортировать строки; "123" > "23" и так далее. Но iirc ascii занимает после чисел, и если да, то то, что вы сделали бы, это создать динамическое свойство NSNumber (которое поддерживает метод compare) и использовать метод numberFromString:, чтобы сделать число из строки. Затем вы можете указать поле номера в сортировке. В интерфейсе:
@property NSString *stringIsaNumber; // in the data model
@property NSNumber *number;
в реализации:
@dynamic stringIsaNumber;
- (NSNumber *) number ;
{ return [self.stringIsaNumber numberFromString]; }
- (void) setNumber:(NSNumber *)value;
{ self.stringIsaNumber = [NSString stringWithFormat:@"%5i",value) }
ps plz прощает ошибки кодирования, это не в моей голове.