【问题标题】:iOS Crash: " this class is not key value coding-compliant for the key url"iOS 崩溃:“此类不符合键 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,因为有时我得到的数据是作为字符串而不是字典返回的。

标签: objective-c dictionary crash


【解决方案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。恭喜;)
    • 如解释在这种情况下,在类中调用未定义方法的崩溃....没有太多要添加的
    猜你喜欢
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多