0
votes

I am using NSComparator to sort objects in NSArray. When the code is not ARC enabled then comparator gives different results to when code is ARC enabled.

Following is my Code snippet:

- (NSArray *)sortedToolsInfoArrayWithKey {
    NSArray *aReturnVal = nil;
    NSArray *aToolsInfoArray = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ToolsData" ofType:@"plist"]];

aReturnVal = [aToolsInfoArray sortedArrayUsingComparator:(NSComparator)^(NSDictionary *a, NSDictionary *b) {
    [[a valueForKey:@"selectionCount"] compare:[b valueForKey:@"selectionCount"]];
}];

[aToolsInfoArray release];
return aReturnVal;

}

This same method is written in Non-ARC code where I need the same kind of sorted array, Note that, my requirement is I need to sort the same array picked from same pList file in two different files, one of the file is ARC enabled while other file isnt ARC enabled. But when I am doing that, I am getting exactly opposite sorting order and when I disable the ARC , the problem is solved.

I am not being able to understand the logic behind different behaviour of NSComparator to sort arrays in ARC and non-ARC enabled files.

Thanks..

3
Update your question with a few entries of your plist file so we can see what you are working with.rmaddy

3 Answers

3
votes

You don't return a value from your comparator block:

aReturnVal = [aToolsInfoArray sortedArrayUsingComparator:^(id a, id b) {
    NSDictionary *adict = (NSDictionary *)a;
    NSDictionary *bdict = (NSDictionary *)b;
    return [[adict objectForKey:@"selectionCount"] compare:[bdict objectForKey:@"selectionCount"]];
}];

(plus use objectForKey rather than valueForKey, which is the KVC accessor).

EDIT Missed the block syntax you were using is incorrect too (thanks to @Ivan Genchev).

1
votes

As a follow-on to the answer by "trojanfoe", you have the wrong syntax for the block. You need:

aReturnVal = [aToolsInfoArray sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *a, NSDictionary *b) {
    return [[a valueForKey:@"selectionCount"] compare:[b valueForKey:@"selectionCount"]];
}];

Let Xcode's code completion fill all of that in for you. It avoids the kind of mistakes you have.

0
votes

You can also use NSSortDescriptor to sort your array.

NSArray *testArray = @[@{@"selectionCount":@"3"},
            @{@"selectionCount":@"1"},
            @{@"selectionCount":@"7"},
            @{@"selectionCount":@"2"}];
NSLog(@"testArray: %@", testArray);
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"selectionCount" ascending:YES];
NSArray *sortedTestArray = [testArray sortedArrayUsingDescriptors:@[sortDescriptor]];
NSLog(@"sortedTestArray: %@", sortedTestArray);