启用 ARC 后,NSComparator 在排序 NSArray 时改变行为
Posted
技术标签:
【中文标题】启用 ARC 后,NSComparator 在排序 NSArray 时改变行为【英文标题】:NSComparator changes behaviour while sorting NSArray when ARC is enabled 【发布时间】:2014-01-30 15:18:55 【问题描述】:我正在使用 NSComparator 对 NSArray 中的对象进行排序。当代码未启用 ARC 时,比较器会给出与启用 ARC 时不同的结果。
以下是我的代码 sn-p:
- (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 的文件中的数组进行排序的不同行为背后的逻辑。
谢谢..
【问题讨论】:
用您的 plist 文件中的一些条目更新您的问题,以便我们看到您正在处理的内容。 【参考方案1】:您没有 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)。
【讨论】:
return
很好。但是缺少return
不会导致编译器错误吗?
@rmaddy 是的,我希望它会。我假设 OP 已经发布了他的实际代码,不过......
刚刚尝试过,它不会导致错误,甚至不会导致警告,因为他正在将该块投射到NSComparator
@rmaddy 请特别参阅NSObjCRuntime.h
和typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
。
@IvanGenchev 不错。错过了。【参考方案2】:
作为“***foe”答案的后续,您的块语法错误。你需要:
aReturnVal = [aToolsInfoArray sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *a, NSDictionary *b)
return [[a valueForKey:@"selectionCount"] compare:[b valueForKey:@"selectionCount"]];
];
让 Xcode 的代码完成功能为您填写所有内容。它避免了你所犯的那种错误。
【讨论】:
【参考方案3】:您还可以使用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);
【讨论】:
以上是关于启用 ARC 后,NSComparator 在排序 NSArray 时改变行为的主要内容,如果未能解决你的问题,请参考以下文章
如何在 xcode 中将启用 ARC 的 .a 文件添加到非 ARC 项目