NSDictionary 获取值作为字符串不会抱怨但 lenngth 或 isEqualToString 崩溃

Posted

技术标签:

【中文标题】NSDictionary 获取值作为字符串不会抱怨但 lenngth 或 isEqualToString 崩溃【英文标题】:NSDictionary get value as string does not complain but lenngth or isEqualToString crashes 【发布时间】:2019-04-01 16:42:37 【问题描述】:

我收到了如下所示的 Json 作为响应消息。

data:
    type = DATA;
    version = "4.51";

我在下面的方法中处理的,从调试器看起来那个版本号是字符串。

-(void)processResponse:(NSDictionary *)responseDictionary
    NSString *version = [responseDictionary valueForKey:@"version"];
    if([version isEqualToString:@"4.51"]) //line 3
        NSLog(@"do something"); //crashes
    

但是第 3 行崩溃了。 我的问题是为什么这条线会崩溃?处理这种类型的字典消息的最佳方法是什么?

【问题讨论】:

能否分享崩溃日志?似乎版本不是 NSString,并且不响应 isEqualToString 调用。 是的,这不是字符串,但从 NsLog 我认为它是一个字符串。我的问题是我怎么能意识到这不是一个字符串。什么是最好的处理方法,它不会崩溃。 似乎 responseDictionary[@"version"] 不是字符串。这意味着您应该首先检查您的 JSON 架构。 可能不相关但永远不要使用valueForKey 从字典中获取单个值,除非您可以解释为什么明确需要 KVC。使用-首选-密钥订阅(responseDictionary[@"version"])或objectForKey[responseDictionary objectForKey:@"version"] @VladimirObrizan,如果我没有架构的话。我应该使用什么预防代码? 【参考方案1】:

如果这是源自您的程序之外的数据,您必须始终检查类型。

-(void)processResponse:(NSDictionary *)responseDictionary 
    id value = responseDictionary[@"version"];
    if ([value isKindOfClass: [NSString class]]) 
        NSString *version = value;
        if ([version isEqualToString: @"4.51"]) 
            NSLog(@"do something"); //crashes
        
    

如果这就是你要做的全部,那么你可以用&&短路缩短一点,如果你小心的话。

-(void)processResponse:(NSDictionary *)responseDictionary 
    NSString *version = responseDictionary[@"version"];
    if ([version isKindOfClass: [NSString class]] 
        && [version isEqualToString: @"4.51"]) 

        NSLog(@"do something"); //crashes
    

对此要非常小心,因为这意味着version 存在于此if 块之外,并且可能不是正确的类型。

同样,如果这正是您的问题,您还可以使用isEqual: 来简化它,它适用于所有NSObject

-(void)processResponse:(NSDictionary *)responseDictionary 
    id version = responseDictionary[@"version"];
    if ([version isEqual: @"4.51"]) 
        NSLog(@"do something"); //crashes
    

【讨论】:

感谢您的回答,第一种方法对我来说看起来更强大。我可以检查字符串或数字,然后做这些事情。

以上是关于NSDictionary 获取值作为字符串不会抱怨但 lenngth 或 isEqualToString 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

在 NSDictionary 中强制转换字符串值以使应用程序崩溃

在 NSDictionary 中检测 Null 值

NSDictionary:将 NSString 键转换为小写以在其上搜索字符串

将选择器作为值存储在 NSDictionary 中

获取 NSManagedObject 的属性作为 NSDictionary

AFNetworking 将 NSDictionary 作为单个数组值发送,而不是作为完整对象发送