Search code examples
iosobjective-csortingnsfetchedresultscontrollernssortdescriptor

Possible to use "self" with NSSortDescriptor to sort by the object itself, rather than object's property? (Core Data / NSFetchedResultsController)


NSSortDescriptor has the method sortDescriptorWithKey:ascending:selector:.

This takes the object being sorted, finds object's the Key-Value Coding property for key, then sends that property the stated selector.

I would instead like to send the object itself the selector, to directly sort the object by one of it's methods.

I have tried key @"self", which fails with the following error:

[NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES selector:@selector(compare:)]; 

'NSInvalidArgumentException', reason: 'keypath #self not found in entity

Is there any way to sort using one of the object's methods, rather than one of the property's?

(BTW, I can't use sortDescriptorWithKey:ascending:comparator: due to Core Data. This will also be used with an NSFetchedResultsController and delegate.)

EDIT:

Full code for what I'd like to do, with Core Data + NSFetchRequest:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"MYClass" inManagedObjectContext:ManagedObjectContext]];
[request setFetchBatchSize:20];

// This is where I am having the problem. Self?
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES selector:@selector(compare:)];
[request setSortDescriptors:@[sortDescriptor]];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"hidden != %@", @YES];
[request setPredicate:predicate];

NSFetchedResultsController *newController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[[ATBackend sharedBackend] managedObjectContext] sectionNameKeyPath:@"sectionKeyPath" cacheName:@"myCache"];

newController.delegate = self;
_fetchedMessagesController = newController;

Solution

  • You can use NSSortDescriptor with the self key, and it works normally.

    But if you use a custom class, you should override the isEqual: and hash functions of your class

    Update for Core Data:

    In your case the method I described may not work, looks like NSFetchedResultsController and arrays use Sort Descriptors differently.

    With Core Data, the NSSortDescriptor key path must be a Core Data property/relationship of your custom NSManagedObject class.

    I suggest to you create a separate property for your class MYClass, called order of number or string type, and update it when class did change. Then you can use this property for sorting in NSFetchedResultsController.