ios85
ios85

Reputation: 2134

sortedArrayUsingSelector what is it doing?

I am still new to objective-c and am trying to figure out what this statement is doing exactly.

[names allKeys] sortedArrayUsingSelector:@selector(compare:)];

I know that allKeys is getting all the keys from my dictionary. I know that sortedArrayUsingSelector is sorting my array im creating. Then im calling the compare method, that is where I am lost what is this doing? From the document on apple it says that "Returns an NSComparisonResult value that indicates whether the receiver is greater than, equal to, or less than a given number." I dont understand how it is sorting based of that method.

Upvotes: 12

Views: 17606

Answers (5)

Jinkal Jagani
Jinkal Jagani

Reputation: 17

The new array contains references to the receiving array’s elements, not copies of them.
The comparator message is sent to each object in the array and has as its single argument another object in the array.
For example, an array of NSString objects can be sorted by using the caseInsensitiveCompare: method declared in the NSString class. Assuming anArray exists, a sorted version of the array can be created in this way:

NSArray *sortedArray =
     [anArray sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

Upvotes: 1

bneely
bneely

Reputation: 9093

- (NSComparisonResult)compare:
{
    // if (value of firstObject) < (value of secondObject)
        // return NSOrderedAscending
    // else if (value of firstObject) == (value of secondObject)
        // return NSOrderedSame
    // else
        // return NSOrderedDescending
}

Upvotes: 7

Joel Kravets
Joel Kravets

Reputation: 2471

NSArray * sortedKeys = [[names allKeys] sortedArrayUsingSelector:@selector(compare:)];

The above code returns a sorted array of the dictionary keys using the selector you provide. The selector is actually the function that will be called on the object that is being sorted in your array. In this case your array contains strings so in the actual NSArray sorting code the following would be happening,

//...
[key1 compare:key2];
//..

If you passed in a different selector lets say @selector(randomFunction:) then in the sorting code the following would happen

//..
[key1 randomFunction:key2];
//..

Since NSString does not respond to the selector randomFunction you would get an error. If you wanted to create your own type of comparison function you would need to add a category to the class that the array contains (in your case a category to NSString).

A better way to sort an array is to use a block statement.

id mySort = ^(NSString * key1, NSString * key2){
    return [key1 compare:key2];
};


NSArray * sortedKeys = [[names allKeys] sortedArrayUsingComparator:mySort];

The reason it's a better way is sorting any objects is very easy to do.

id mySort = ^(MyObject * obj1, MyObject * obj2){
    return [obj1.title compare:obj2.title];
};


NSArray * sortedMyObjects = [myObjects sortedArrayUsingComparator:mySort];

Upvotes: 25

Wolfgang Schreurs
Wolfgang Schreurs

Reputation: 11834

The -sortedArrayUsingSelector: method in your example calls the -compare: method on the objects in the array. For some objects Apple has already implemented a -compare: method, for example if you read through the NSString documentation, you'll find a -compare: method implemented. You can also call custom comparison methods on your own custom objects if you've implemented a comparison method in these objects. Please note the comparison method doesn't have to be called -compare:, of importance is only the return value (NSComparisonResult) and the object the method receives.

Upvotes: 3

jrturton
jrturton

Reputation: 119272

You should probably be using caseInsensitiveCompare: in this situation since you are most likely ordering an array of strings (keys from a dictionary).

You've assumed that sortedArrayUsingSelector is somehow separate to the compare: part of the code. This is not the case. compare: is the selector that is used to sort the array.

The sorting method gives you back an array where each element, when sent the specified selector and the next element in the array, gives the correct sort order.

How NSArray achieves this is not public but at root, the selector you define is used to compare pairs of objects from within the array, the result of which informs their placement in the sorted array.

Upvotes: 0

Related Questions