3

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;
pkamb
  • 33,281
  • 23
  • 160
  • 191
  • What do you mean "sort the object by one of it's methods"? What is the form of this method? Does it take another object and what does it return? Is it named `compare:`? If not, have you tried passing its selector to the sort descriptor constructor? What do you mean when you say that `@"self"` doesn't work? What exactly happens and how does it differ from what you want? – Ken Thomases Aug 10 '15 at 23:01
  • @KenThomases The method would match the description in the `NSSortDescriptor` docs (must essentially match `compare:`). But the problem I'm hitting is in the object I am sending the selector to, not in the selector itself. Want to send it to `object`, can only send it to `object.property`. – pkamb Aug 10 '15 at 23:05
  • You still haven't said what exactly fails when you specify `@"self"` and `@selector(yourComparisonMethod:)`. It works in general with sort descriptors. There may be an issue with Core Data, but it's impossible to figure out unless you explain what's happening. – Ken Thomases Aug 11 '15 at 00:13
  • @KenThomases Added, thanks. – pkamb Aug 11 '15 at 00:18

1 Answers1

3

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.

pkamb
  • 33,281
  • 23
  • 160
  • 191
Vitalii Gozhenko
  • 9,220
  • 2
  • 48
  • 66
  • But how could this work? [Apple's own documentation for this method](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSSortDescriptor_Class/index.html#//apple_ref/occ/clm/NSSortDescriptor/sortDescriptorWithKey:ascending:selector:) says that the parameter's type must be `NSString`. – SevenBits Aug 10 '15 at 22:07
  • But you send it as `NSString` parameter, but it called `self`. – Vitalii Gozhenko Aug 10 '15 at 22:09
  • `[self.objects sortUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES]]];` This code works as normal with array of `objects`, which is array of `NSDate` objects – Vitalii Gozhenko Aug 10 '15 at 22:09
  • @SevenBits with Key-Value, a property is represented as a string https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueCoding/Articles/BasicPrinciples.html – JordanC Aug 10 '15 at 22:10
  • @JordanC Sorry, it's been a long day. I thought the OP was asking about passing the keyword `self` to the method. Whoops... – SevenBits Aug 10 '15 at 22:12
  • @SevenBits Monday, man, I feel ya. This answer should work though. I'm deleting mine. Last chance to upvote ;) – JordanC Aug 10 '15 at 22:15
  • 1
    @VitaliyGozhenko Perhaps everything is more troublesome when paired with Core Data. When I pass `@"self"` I get: `'NSInvalidArgumentException', reason: 'keypath #self not found in entity ` – pkamb Aug 10 '15 at 22:38
  • Can you share whole code about fetching from Core Data and using sort descriptor? – Vitalii Gozhenko Aug 10 '15 at 23:12
  • @VitaliyGozhenko Added to OP. – pkamb Aug 10 '15 at 23:38