适用于iOS的NSNumericSearch解决方案

时间:2011-12-30 13:51:03

标签: objective-c ios

我有一个NSString,我想用数字搜索。似乎NSNumericSearch是合适的解决方案,但显然只比较:,caseInsensitiveCompare:,localizedCompare:和localizedCaseInsensitiveCompare:在iOS中进行提取时用作排序选择器。 (这是一个核心数据项目)。据我所知,这与SQLite后备数据存储有关。

我已经尝试将字符串转换为NSNumber。 ARC有一个错误,因为NSNumber基本上是一个int。

总之,我想用数字(1,2,11,25)对字符串进行排序,而不是(1,11,2,25)。我会很感激任何解决方案。

编辑:(我为上述情况道歉。当时我远离电脑,匆忙。)

有限排序描述符的信息来自Isted& amp;的最后一页。 Harrington 2011年出版的“iOS数据核心数据”。

  

使用排序描述符进行提取时,您需要将自己限制在iOS上的以下选择器:   相比:,   caseInsensitiveCompare :,   localizedCompare :,   localizedCaseInsensitiveCompare:

为了澄清,我写了一个这样的类别:

@interface NSString (SizeComparison)
-(NSComparisonResult)sizeCompare:(NSString*)otherString;
@end
@implementation NSString (SizeComparison)
-(NSComparisonResult)sizeCompare:(NSString*)otherString {
return [self compare:otherString options:NSNumericSearch];
}
@end

fetchedResultsCntroller中的排序描述符如下:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"size" ascending:YES selector:@selector(sizeCompare:)];

它返回此错误:

* 由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'不支持的NSSortDescriptor选择器:sizeCompare:'

这似乎与Isted&哈灵顿的陈述。

另外,当我说我投入NSNumber时,我试图简短,但显然不清楚。这就是我所做的:

NSNumberFormatter *numformatter = [[NSNumberFormatter alloc] init];
numformatter.numberStyle = NSNumberFormatterNoStyle;
self.objectToEdit.size = [numformatter numberFromString:self.sizeTextField.text];

所以,我想用数字(1,2,11,25)对NSString进行排序,而不是(1,11,2,25)。我仍然会感谢任何解决方案。

4 个答案:

答案 0 :(得分:8)

我终于找到了数字排序字符串问题的答案。它涉及直接使用块。对于我的排序描述符,它只是:

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"size" ascending:NO comparator:^(id obj1, id obj2) { return [obj1 compare:obj2 options:NSNumericSearch]; }];

这允许NSStrings以数字方式排序(1,11,2,25)。

我不确定为什么某个类别不起作用。以为我会为遇到同样问题的其他人发布答案。

答案 1 :(得分:0)

  

显然只比较:,caseInsensitiveCompare:,localizedCompare:和localizedCaseInsensitiveCompare:在iOS中进行提取时用作排序选择器

真的?我认为问题更多的是你使用的选择器只能接受一个参数(另一个要比较的字符串),你需要使用-compare:options:进行数值比较。

尝试编写类别方法进行比较,例如

@interface NSString(NumericCompare)

-(NSComparisionResult) compareNumerically: (NSString*) anotherString;

@end

@implementation NSString(NumericCompare)

-(NSComparisionResult) compareNumerically: (NSString*) anotherString
{
    return [self compare: anotherString options: NSNumericSearch];
}
  

我已经尝试将字符串转换为NSNumber。 ARC有一个错误,因为NSNumber基本上是一个int。

你不能只是将NSSstring转换为NSNumber,你只是投射指针,而不是指向的对象。你可以这样做

NSNumber* number = [NSDecimalNumber numberWithString: myStringValue];

NSDecimalNumberNSNumber的子类。

答案 2 :(得分:0)

如果确实存在限制(事实上,我在代码中仅使用localizedCaseInsensitiveCompare:),您应该可以使用sortDescriptorWithKey:ascending:comparator:并在块中使用NSNumericSearch。

答案 3 :(得分:0)

在没有NSNumericSearch的情况下,我能够完成所需的工作。

我更改了核心数据结构,将'size'属性更改为Integer16,并将模型类属性'size'从NSString更改为NSNumber,并进行了轻量级迁移。

然后我使用以下方法修改了现有代码:

aString = [aNumber stringValue];

NSNumberFormatter *numformatter = [[NSNumberFormatter alloc] init];
numformatter.numberStyle = NSNumberFormatterNoStyle;
bNumber = [numformatter numberFromString:bString]

适当地更改NSString和NSNumber对象。

现在它像我想要的那样排序。

总之,我避免了通过改变数据结构对NSStrings进行数字排序的整个问题。

排序描述符只是fetchedResultsController中使用的基本描述符:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey1 ascending:YES];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"size" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor,sortDescriptor2, nil];

感谢大家的投入。抱歉,麻烦。