我想检查JSON对象是否为NSString,如果不是,请为其分配默认字符串。我的最终目标是防止崩溃,无论如何都为属性分配适当的值。这是我使用的数据模型的示例,其中dict
是API返回的JSON字典。
Data *data = [[self alloc] init];
data.name = [NSString validateString:dict[@"name"] defaultString:@""];
data.status = [NSString validateString:dict[@"status"] defaultString:@"OPEN"];
这是我正在使用的类别方法validateString
。
+ (NSString *)validateString:(NSString *)aString defaultString:(NSString *)defaultString {
if ([aString isKindOfClass:[NSString class]]) {
return aString;
}
return defaultString;
}
答案 0 :(得分:2)
强制转换(NSString *)aString
,然后问这是否实际上是NSString,是没有意义的,也是非常不好的做法。
还可以,如果没有的话怎么办?
从词典中获取内容时,您所知道的就是得到id
。不要承担更多的责任。
我建议写得很简单:说出你的意思,然后说出你的意思。这是Objective-C中的最佳实践。否则,动态键入和“零欺骗”会导致您陷入细微的错误。在这种情况下,您可能不会遇到任何麻烦,但是不良习惯就是不良习惯,最好不要让它们首先形成。我会这样重写:
+ (NSString *) checkType:(nullable id)obj defaultString:(NSString *)def {
if (obj == nil || ![obj isKindOfClass:[NSString class]]) {
return def;
}
return obj;
}
答案 1 :(得分:0)
就像其他注释中提到的那样:如果要防止崩溃,还需要检查它是否为nil
,尤其是将来是否有机会将代码移植到Swift时。
为澄清我的最后一句话,即使aString
为nil
,下面的行在Objective-C中也有效:
if ([aString isKindOfClass:[NSString class]]) {
这是因为,按照制作Objective-C的方式,在nil
对象上调用函数会返回nil
,因此if
将被视为false
,并且该函数将返回defaultString
。是的...当他们创建Objetive-C时,这肯定不是一个好主意,因为这会导致很多错误。以下是有关该行为的更多详细信息:
https://stackoverflow.com/a/2696909
无论如何,在检查对象的类型之后仅强制转换对象也是一种好习惯,因此,我建议您将函数修改为:
+ (NSString *)validateString:(id)obj defaultString:(NSString *)defaultString {
if (obj != nil && [obj isKindOfClass:[NSString class]]) {
return (NSString*)obj;
}
return defaultString;
}
每个实现NSObject*
的对象都有isKindOfClass:
(NSDictionary*
仅存储实现NSObject*
的对象),因此我们不需要检查该对象是否响应它。另外,即使我们想要,respondsToSelector:
也是NSObject*
的功能。
仍然,您使用的方法仍然有效。上面修改的功能仅适用于更好的做法,并且可以避免将来出现需要将此代码移植到Swift(或任何其他语言)的问题。
编辑:根据@matt的建议更新了代码。