Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C compareTo:

Is there a standard mechanism for comparing two objects in Objective-C?

I know the isEqual method, but I am not looking for exact equality but rather less than / more than / equal kind of comparison.

In Java we have compareTo: that does it, is there anything like that in Objective-C?

like image 916
foFox Avatar asked Aug 22 '13 12:08

foFox


2 Answers

In Objective-C there's no standard protocol for comparison, like the Comparable<T> interface in Java, but some classes from the Foundation framework define a compare: method.

NSString and NSNumber are some examples.

If you want to provide your own comparison method for a custom class, I suggest that you stick to conventions and provide a method with the following signature

- (NSComparisonResult)compare:(MyClass *)object;

NSComparisonResult is an enum defined as follows

enum {
   NSOrderedAscending = -1,
   NSOrderedSame,
   NSOrderedDescending
};
typedef NSInteger NSComparisonResult;

NSOrderedAscending means that the left operand is smaller than the right one (and from this you get the others).

NOTE

It's worth stressing that Objective-C and the closely related Foundation Framework are built on conventions. They are not just an idiomatic way of writing, as sometimes the implementation relies on them. For instance if you instanciate a NSSortDescriptor without specifying a custom selector, the default implementation will call compare: on the objects. (hat-tip to David Ronnqvist for the example)

Another notable example is the naming convention for methods. Instance methods starting with init are expected to return an object with a +1 retain count. This was such strong convention, that with the advent of ARC it has been formalized and built into the compiler.

To wrap it up: conventions are always important. In Objective-C sometimes they are fundamental.

like image 140
Gabriele Petronella Avatar answered Nov 15 '22 14:11

Gabriele Petronella


You should implement

- (NSComparisonResult)compare:(CustomClass *)otherObject;

and return either NSOrderedAscending, NSOrderedDescending or NSOrderedSame.

Even though NSObject doesn't implement it, it is the method being used throughout the system for comparisons. For example:

NSArray *unsorted = @[[CustomClass new], [CustomClass new], [CustomClass new]];
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"self" 
                                                       ascending:NO]
NSArray *sorted = [unsorted sortedArrayUsingDescriptors:@[sort]];

will call compare: on the "CustomClass" and use the results to sort the array. Note that if your class doesn't implement compare: it will crash because of this (when sorting).

like image 44
David Rönnqvist Avatar answered Nov 15 '22 12:11

David Rönnqvist