所以,在这个问题上挣扎了太久,没有太多的文档可以继续,我想我会为那些比我更笨的人分享我的经验。可能有更清洁的方法可以实现我所做的,所以请随时提出改进建议。
这是我想做的事情:
我有一个管理 NSManagedObjects 的 NSArrayController(比如 Thing)。这些对象有一个 NSString 类型的 name 属性。我想使用托管对象的名称对数组控制器的数组进行排序。对可变字符串数组进行排序的常用方法应该是:
[myMutableArrayOfStrings sortUsingSelector:@selector(caseInsensitiveCompare:)];
或者:
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];
NSArray *descriptorArray = [NSArray arrayWithObject:sortDescriptor];
[myArrayController setSortDescriptors:descriptorArray];
但是,如果名称恰好是数字,caseInsensitiveCompare: 将在 8 之前排序 11(例如)。此外,我希望将 a11b 的名称排序在 a8b 之后,这意味着我需要将托管对象的名称分成数字和非数字字符组,然后分别进行比较。
我想出的是创建一个 NSString 类别。
头文件:
#import <Foundation/Foundation.h>
@interface NSString (MyString)
- (NSComparisonResult)myCustomCompare:(NSString *)anotherString;
@end
实现文件:
#import "MyString.h"
@implementation NSString (MyString)
- (NSComparisonResult)myCustomCompare:(NSString *)anotherString {
elaborate chopping up of strings into substrings..
For each of the 2 strings I made an NSMutableArray.
Then I determined if these substrings were NSNumbers, which have their own compare:, or NSStrings (caseInsensitiveCompare:)
Then I return an NSComparisonResult (NSOrderedAscending, NSOrderedSame or NSOrderedDescending)
}
@end
然后,在我的 Thing ManagedObject 的实现文件中,我覆盖了
- (NSComparisonResult)compare:(Thing *)anotherThing {
return [self.name myCustomCompare:anotherThing.name];
}
还需要在 Thing 类中导入 MyString.h。
现在,使用
[[myArrayController arrangedObjects] sortUsingSelector:@selector(compare:)];
奇迹般有效。
只有一件事一直困扰着我。如果事物的名称属性包含十进制数字,例如 a1.4b 和 a1.39b,我如何能够将它们与名称隔离?(a1.4b 将错误地排在 a1.39b 之前)更糟糕的是,用户可以输入事物的名称为 1.3.55 ...