This is my first post, so I'm sorry if I do not respect all the agreements, although I will try my best. I always found solutions to my problems on SO before, but I was completely stuck on Cocoa's rather complicated problem.
I am trying to do complex sorting in a list of CoreData objects. I have a catalog consisting of book objects that can be part of the Saga (first book and its sequels). Simplified structures look like this:
@interface Book : NSManagedObject
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSNumber * tomaison;
@property (nonatomic, retain) Saga *fromSaga;
@interface Saga : NSManagedObject
@property (nonatomic, retain) NSString * title;
I am trying to execute a query on my CoreData db, in a book:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:context];
and I need a view in three stages:
1) Sort by book Genre (not included in the code above, because it is not needed), which is executed using
NSSortDescriptor* mainSort = [[NSSortDescriptor alloc] initWithKey:@"ofGenre.title" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
2) Sorting by the name of the saga, if the book is part of the saga
NSSortDescriptor* secondarySort = [[SagaTitleSortDescriptor alloc] initWithKey:@"fromSaga" ascending:YES];
If a custom sort descriptor is defined as follows:
#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]];
}
, ?
!
EDIT: