Christian Schnorr
Christian Schnorr

Reputation: 10786

Sorting objects by the return value of a method

I recently encountered some problems while trying to sort a set of objects.

The objects I'd like to sort are subclasses of NSManagedObject.
I want to sort the objects by a 'global_index', which is, however, not a property in my model. It's just a getter -(NSInteger)globalIndex {...} each of the objects implements. Inside this method, I do some complex calculation which cannot be done with a simple sort descriptor.

Now, my question: Is there a way to make an NSSortDescriptor sort the objects by the return value of a method?

I really want to use a sort descriptor because it's (IMO) the only way to make use of NSFetchedResultsController's cool features. Or is there a way to tell the controller how to sort the fetched objects? Like...
- (NSArray *)sortObjects:(NSSet *)objects {...}

Thanks in advance!

Upvotes: 1

Views: 223

Answers (3)

tc.
tc.

Reputation: 33592

According to the Core Data Programming Guide,

The SQL store, on the other hand, compiles the predicate and sort descriptors to SQL and evaluates the result in the database itself. This is done primarily for performance, but it means that evaluation happens in a non-Cocoa environment, and so sort descriptors (or predicates) that rely on Cocoa cannot work. The supported sort selectors are compare: and caseInsensitiveCompare:, localizedCompare:, localizedCaseInsensitiveCompare:, and localizedStandardCompare: (the latter is Finder-like sorting, and what most people should use most of the time). In addition you cannot sort on transient properties using the SQLite store.

The easy workaround is to save the order with each object (which is a pain when you need to insert an object between two others, but that's a problem with trying to implement an efficient ordered collection in a database).

Upvotes: 2

Perception
Perception

Reputation: 80623

You should be able to 'trick' NSSortDescriptor into using your global index method like it would any regular accessor method (the accessor should conform to the expectations of Key-Value Programming). In other words, treat globalIndex as a property of your NSManagedObject subclasses and have the following methods in each one of them.

-(NSInteger) globalIndex {
    ...
}


-(void) setGlobalIndex: (NSInteger) idx {
    ...
}

To make things even easier, you can define a subclass of NSManagedObject with your extra methods and extend your subclasses from that (or create a Category, either way). Should work just fine.

Upvotes: 0

Caleb
Caleb

Reputation: 125007

Have you tried simply passing @"globalIndex" as the sort descriptor's key? That should work fine since there's an accessor for that key.

Upvotes: 1

Related Questions