如何解决使用 NSString 作为 NSNumber 或使用 NSNumber 作为 NSString?

how to solve using NSString as NSNumber or using NSNumber as NSString?

在我的项目中,旧代码太多,有时会导致有关变量class错误的问题。

在大多数情况下,NSNumber 变量NSString 值 赋值,反之亦然。后来变量使用了一些 NSNumber 方法并崩溃了。

有时我会使用下面的代码

NSNumber *feed_id = nil;
id object = self.config.operationData.feedID;
if ([object isKindOfClass:[NSNumber class]]) {
    feed_id = object;
} else if ([object isKindOfClass:[NSString class]]) {
    feed_id = [(NSString *)object numberValue];
}

但我认为这不是一个舒服的处理方式,因为我不知道哪里出了问题,而且到处使用这段代码似乎有点愚蠢。

所以我需要一种聪明的方法来检测问题,并在可能的情况下将变量类型转换为我需要的类型。

NSNumberNSString 都响应 integerValue,所以如果值应该是整数,这是一个可靠的方法

id object = self.config.operationData.feedID;
NSNumber *feed_id = [NSNumber numberWithInteger: object.integerValue];

但我建议重构整个代码以使其成为类型安全的。

您已经获得了接受任一类型并返回 NSNumber 的代码...您需要做的就是使其易于使用。你可以把它放在 NSNumber 类别的方法中,比如:

@interface NSNumber (BandAid)
+ (NSNumber*)numberFromNumberOrString:(id)numberOrString;
@end

@implementation NSNumber (BandAid)
+ (NSNumber*)numberFromNumberOrString:(id)numberOrString {
    NSNumber *number = nil;
    if ([numberOrString isKindOfClass:[NSNumber class]]) {
        number = object;
    }else if ([numberOrString isKindOfClass:[NSString class]]) {
        number = [(NSString *)object numberValue];
    }
    return number
}
@end

现在您可以轻松调用:

NSNumber *feed_id = [NSNumber numberFromNumberOrString:self.config.operationData.feedID];

以及您代码中其他地方的类似内容。更重要的是,您可以在该方法中添加调试代码,以帮助您追踪所有错误传递字符串的地方,这样您就可以消除问题的根源,而不仅仅是贴上创可贴。

您 can/should 做的其他事情包括:

  • 打开所有编译器警告
  • 消除代码产生的任何警告
  • 添加 validation methods 以检查流入您的应用程序的数据