2012-06-25 2 views
3

Это мой первый пост, так жаль, если я могу не уважать все соглашения, хотя я постараюсь изо всех сил. Я всегда находил решения своих проблем на SO раньше, но я полностью придерживаюсь довольно сложной проблемы с какао.Пользовательский NSSortDescriptor на сложном объекте

Я пытаюсь выполнить сложный вид в списке объектов CoreData. У меня есть каталог, состоящий из объектов книги, которые могут быть частью Саги (первая книга и ее сиквелы). Упрощенные структуры выглядеть следующим образом:

@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) Сортировка по жанру книги (не входит в код выше, потому что это не требуется), которое выполняется с:

2) Сортировать по названию Saga, если книга является частью саги

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) Сортировать по Volume нумерацией ЕСЛИ является частью Сага, иначе, сортировать по названию книги. Вот моя проблема, поскольку я не знаю, какой ключ отправить и что добавить в мой дескриптор (я даже не уверен, что это возможно).

NSSortDescriptor* thirdSort = [[SagaTomaisonOrBookTitleSortDescriptor alloc] initWithKey:@"self" ascending:YES]; 

До сих пор, я обнаружил, что @ «я» позволяет отправлять объект быть запрошена, но не похоже, чтобы запросы параметров внутри отправленного объекта. Для справки, есть некоторый код, который я пробовал:

- (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]]; 
} 

Любая идея, что я могу и должен делать?

Спасибо!

EDIT: был тип в последней строке

+0

Является ли эта часть NSFetchRequest? Какое хранилище данных Core Data используется вами? Если это база данных SQL, вы не можете использовать дескрипторы сортировки на основе кода с NSFetchRequest. –

+0

Это действительно часть NSFetchRequest, и я использую стандартную модель CoreData (.xcdatamodel, NSManagedObjectContext и т. Д.). Обратите внимание, что второй дескриптор сортировки работает отлично. – ameunier

ответ

1

Если вы не используете SQL на основе хранилища, вы можете сделать это, передавая себя в качестве ключа и сравнить: как селектор, то осуществить это пользовательский селектор. То есть, сделайте метод в вашем классе книги с именем compare: и просто попросите его выполнить всю вашу логику, а не использовать несколько дескрипторов сортировки.

+0

Это интересно. Однако, похоже, он тоже не работает. Я внедрил пользовательский селектор в классе Book (в более конкретной категории), и он разбился. Я проверил с очень простым тестом: '- (NSComparisonResult) specialCompare: (id) other {return NSOrderedSame; } ' И в ViewController: ' NSSortDescriptor * thirdSort = [[NSSortDescriptor Alloc] initWithKey: @ "я" восходящих: ДА селектор: @selector (specialCompare :)]; ' я делаю что-то неправильно? – ameunier

+0

Дополнительное примечание: я не могу просто переопределить метод compare в книге Book.h, поскольку это не единственное место, где я сравниваю две книги, а в других местах есть другие методы сортировки. – ameunier

+0

Это выглядит хорошо для меня. Где происходит авария? Какое сообщение вы получаете? –

Смежные вопросы