启用ARC时,NSComparator在排序NSArray时更改行为

时间:2014-01-30 15:18:55

标签: ios objective-c sorting automatic-ref-counting comparator

我正在使用NSComparator对NSArray中的对象进行排序。当代码未启用ARC时,比较器会在代码启用ARC时给出不同的结果。

以下是我的代码段:     

- (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;

}
 

这个方法是用非ARC代码编写的,我需要相同类型的排序数组。注意,我的要求是我需要对从两个不同文件中的同一个pList文件中挑选的相同数组进行排序,其中一个文件启用ARC时,其他文件未启用ARC。 但是当我这样做时,我的排序顺序正好相反,当我禁用ARC时,问题就解决了。

我无法理解NSComparator在ARC和非ARC启用文件中对数组进行排序的不同行为背后的逻辑。

谢谢..

3 个答案:

答案 0 :(得分:3)

您没有return来自比较器块的值:

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

(加上使用objectForKey而不是valueForKey,这是KVC访问者。)

编辑错过您使用的块语法也不正确(感谢@Ivan Genchev)。

答案 1 :(得分:1)

作为“trojanfoe”答案的后续内容,您的块语法错误。你需要:

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

让Xcode的代码完成为您填写所有内容。它可以避免你遇到的那种错误。

答案 2 :(得分:0)

您还可以使用NSSortDescriptor对数组进行排序。

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);