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?
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).
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With