Это мой первый пост, так что извините, если я могу не соблюдать все условности, хотя я буду стараться изо всех сил. Раньше я всегда находил решения своих проблем на SO, но я полностью застрял в довольно сложной проблеме Cocoa.
Я пытаюсь добиться сложной сортировки списка объектов CoreData. У меня есть каталог, состоящий из объектов Book, которые могут быть частью Saga (первая книга и ее продолжения). Упрощенные структуры выглядят так:
@interface Book : NSManagedObject
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSNumber * tomaison; //volume numbering
@property (nonatomic, retain) Saga *fromSaga;
@interface Saga : NSManagedObject
@property (nonatomic, retain) NSString * title;
Я пытаюсь выполнить запрос к моей базе данных CoreData в книге:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:context];
и мне нужна сортировка в три этапа:
1) Сортировка по жанру книги (не включена в приведенный выше код, потому что она не нужна), которая выполняется с помощью:
NSSortDescriptor* mainSort = [[NSSortDescriptor alloc] initWithKey:@"ofGenre.title" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
2) Сортировать по названию саги, если книга является частью саги.
NSSortDescriptor* secondarySort = [[SagaTitleSortDescriptor alloc] initWithKey:@"fromSaga" ascending:YES];
Где пользовательский дескриптор сортировки определяется:
#define NULL_OBJECT(a) ((a) == nil || [(a) isEqual:[NSNull null]])
@interface SagaTitleSortDescriptor : NSSortDescriptor {}
@end
@implementation SagaTitleSortDescriptor
- (id)copyWithZone:(NSZone*)zone
{
return [[[self class] alloc] initWithKey:[self key] ascending:[self ascending] selector:[self selector]];
}
- (NSComparisonResult)compareObject:(id)object1 toObject:(id)object2
{
if (NULL_OBJECT([object1 valueForKeyPath:[self key]])) {
if (NULL_OBJECT([object2 valueForKeyPath:[self key]]))
return NSOrderedSame;
return NSOrderedDescending;
}
if (NULL_OBJECT([object2 valueForKeyPath:[self key]])) {
return NSOrderedAscending;
}
return [super compareObject:[(Saga*)object1 title] toObject:[(Saga*)object2 title]];
}
@end
3) Сортировать по нумерации томов, ЕСЛИ это часть саги, в противном случае сортировать по названию книги. Вот моя проблема, так как я не знаю, какой ключ отправить и что поставить в свой дескриптор (я даже не уверен, что это возможно).
NSSortDescriptor* thirdSort = [[SagaTomaisonOrBookTitleSortDescriptor alloc] initWithKey:@"self" ascending:YES];
До сих пор я обнаружил, что @"self" позволяет отправлять запрашиваемый объект, но, похоже, не позволяет запрашивать параметры внутри отправленного объекта. Для справки, есть код, который я пробовал:
- (NSComparisonResult)compareObject:(id)object1 toObject:(id)object2
{
if (NULL_OBJECT([(Book*)object1 fromSaga]) && NULL_OBJECT([(Book*)object2 fromSaga])) {
return [super compareObject:[(Book*)object1 title] toObject:[(Book*)object2 title]];
}
if (NULL_OBJECT([(Book*)object1 fromSaga])) {
return NSOrderedDescending;
}
if (NULL_OBJECT([(Book*)object2 fromSaga])) {
return NSOrderedAscending;
}
return [super compareObject:[(Book*)object1 tomaison] toObject:[(Book*)object1 tomaison]];
}
Любая идея, что я могу и должен сделать?
Спасибо !
РЕДАКТИРОВАТЬ: в последней строке был тип