iOS 崩溃:“此类不符合键 url 的键值编码”

Posted

技术标签:

【中文标题】iOS 崩溃:“此类不符合键 url 的键值编码”【英文标题】:iOS Crash: " this class is not key value coding-compliant for the key url" 【发布时间】:2017-11-14 16:19:13 【问题描述】:

我在 crashlytics 上遇到以下崩溃。

致命异常:NSUnknownKeyException [<__nscfstring> valueForUndefinedKey:]: 这个类对键 url 不符合键值编码。

这是一些用户发生崩溃的地方。

 id url = [[json[@"data"]valueForKey:@"value"]valueForKey:@"url"];

我不确定防止这种崩溃的最佳方法是什么。我相信这是因为 json[@"data"] 在某些情况下是一个 NSString 。所以我相信我应该检查这是否是这样的 NSDictionary。

if ([json[@"data"] isKindOfClass:[NSDictionary class]]) 
     id url = [[json[@"data"]valueForKey:@"value"]valueForKey:@"url"];
    

感谢任何提示或建议。

这是我从这里得到答案后的最终结果。这看起来好吗?为了简单起见,我一开始并没有包含所有代码。

        if ([json isKindOfClass:[NSDictionary class]]) 
            id url = nil;
            id type = nil;

            NSDictionary *data = json[@"data"];

            if ([data isKindOfClass:[NSDictionary class]]) 
                type = data[@"type"];
                NSDictionary *value = data[@"value"];

                if ([value isKindOfClass:[NSArray class]]) 
                    url = [value valueForKey:@"url"];
                

                if ([type isKindOfClass:[NSString class]] && [url isKindOfClass:[NSArray class]] && [url count] != 0) 
                   // do stuff
              
            
         

【问题讨论】:

你为什么用valueForKey:而不是objectForKey:?除非您有明确、具体和可理解的理由,否则不要使用键值编码。 @trungduc 代码现在看起来还好吗?我已经更新了我的答案。 @CurtRand 你应该使用id *value 而不是NSDictionary *value。这更有意义。其他一切看起来都不错。 @CurtRand 还有一个,我认为你不需要检查json 是一种类NSDictionary。我猜,您的jsonNSString,所以只需将jsonNSString 转换为NSDictonary 我必须检查 'json' 是否是 NSDictionary,因为有时我得到的数据是作为字符串而不是字典返回的。 【参考方案1】:

您应该一一检查NSDictionary,以防止崩溃。在下面试试我的代码

NSDictionary *dictionary = json[@"data"];
NSString *output = @"";
if ([dictionary isKindOfClass:[NSDictionary class]]) 
  dictionary = dictionary[@"value"];
  if ([dictionary isKindOfClass:[NSDictionary class]]) 
    output = dictionary[@"url"];
  

NSLog(@"%@", output);

由于在 NSString 值上调用 valueForKey 方法而导致崩溃。如果有人说崩溃的原因是当字典没有这个键时调用valueForKey,那就错了。欲了解更多信息Sending a message to nil in Objective-C

[dictionary isKindOfClass:[NSDictionary class]] 如果dictionary 为nil,则始终返回NO,因此不需要在if statement 中检查dictionary。没意思。

【讨论】:

【参考方案2】:

您的错误意味着 json[@"data"]valueForKey:@"value"] 没有 NSDictionarry,因此它没有 @"url" 键。

valueForKey 是 KVC 方法,对字典使用 objectForKey,并添加更多检查,例如:

        id url = nil;
        NSDictionary *data = [json objectForkey:@"data"];
        if ([data isKindOfClass:[NSDictionary class]]) 
            NSDictionary *value = [data objectForKey:@"value"];
            if ([value isKindOfClass:[NSDictionary class]]) 
                url = [value objectForKey:@"url"];
            
        

【讨论】:

@RomanSimenok 你不需要检查datanil 因为[data isKindOfClass:[NSDictionary class] 将返回NO 如果datanil ;) @trungduc 是的,我知道,但是有什么更快的检查它是否为 nil 或检查它是否不是类?) @RomanSimenok 我猜,检查 nil 将被放在方法 isKindOfClass 的顶部。所以不用担心哪个更快。 @RomanSimenok 再一个,valueForKeyobjectForKey 如果没有 key 对象,则返回 nil。他的崩溃是因为在NSString 上调用valueForKey。恭喜;) 如解释在这种情况下,在类中调用未定义方法的崩溃....没有太多要添加的

以上是关于iOS 崩溃:“此类不符合键 url 的键值编码”的主要内容,如果未能解决你的问题,请参考以下文章

iOS测试常见崩溃

Xcode查看iOS崩溃与崩溃日志分析

存档崩溃中的 iOS 崩溃似乎是块

QuartzCore - iOS8 崩溃

符号化没有崩溃日志的 iOS 崩溃堆栈跟踪

iOS CAMImagePickerCameraViewController 在 iOS 10.3.1 中崩溃