【问题标题】:iOS How to check if valueForKey exist or not?iOS 如何检查 valueForKey 是否存在?
【发布时间】:2015-05-15 13:55:34
【问题描述】:

我还有一个关于检查 valueForKey 是否存在的问题。 这是我的代码:

id _jsonId = [NSJSONSerialization JSONObjectWithData:[_json dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&_error];
Monday = [[NSMutableArray alloc] init];
if ([_jsonId valueForKey:@"Mon"]!= Nil) {
    _keyMon = [_jsonId valueForKey:@"Mon"];
    [Monday addObject:@"Monday"];
    for (int i=0; i<5; i++) {
        if ([_keyMon objectAtIndex:i]!=[NSNull null]) {

            [Monday addObject:[_keyMon objectAtIndex:i]];
        }
    }

} else {
    [_keyTues addObject:@"No Class For Today"];
    [Monday addObject:[_keyMon objectAtIndex:1]];
}

这个想法是,如果 _jsonId valueForKey 什么都没回来,我可以添加这个 NSStringaddObject:@"No Class For Today 以防 XCode 告诉我: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'

就像它现在告诉我的那样。任何人有任何解决方案? 我试过if ([_jsonId valueForKey:@"Mon"]!= Nil) 没用。 我试过if ([_jsonId valueForKey:@"Mon"]!= nil) 没用。 我试过if ([_jsonId valueForKey:@"Mon"]!= (id)[NSNull null]) 没用。 我试过if ([_jsonId valueForKey:@"Mon"]!= [NSNull null) 没用。

我知道_jsonId valueForKey 作为指针返回,但我不知道如何检查指针是否为空(如果我是正确的,则在Objective-C 中为nil)。请帮帮我。

更新: 我尝试过使用 objectForKey,这是一个代码(_jsonId objectForKey 为零,我知道可以尝试测试代码)

if (_jsonId[@"Sun"]== nil) {
    [_keySun addObject:@"No Class For Today"];
    [Monday addObject:[_keySun objectAtIndex:1]];
            }
else{
   _keySun = [_jsonId objectForKey:@"Sun"];
   [Monday addObject:@"Sunday"];
   for (int i=0; i<5; i++) {
       if ([_keySun objectAtIndex:i]!=nil) {

           [Monday addObject:[_keySun objectAtIndex:i]];
       }
}
}

不过,XCode 告诉我我要在 NSArray 中添加一个 nil。

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'

这快把我逼疯了……

【问题讨论】:

  • objectForKey 有什么问题?
  • @trojanfoe 在某些情况下我可能会遇到一个空的objectForKey,并且我无法将nil对象添加到NSArray中
  • 这与它无关。在将对象放入集合类之前,您可以测试(就像现在一样)nil
  • @trojanfoe 是的,这正是我一直想做的事情,我试图检测 [_jsonId valueForKey] 是否为零,如果它为零,我可以做一些事情。但我似乎没有做正确的事。
  • 首先阅读@Tommy 的回答;他还提倡改用objectForKey:,并很好地说明了原因。

标签: ios objective-c


【解决方案1】:

_jsonId 定义为:

id _jsonId = [NSJSONSerialization JSONObjectWithData:[_json dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&_error];

... 将是一个数组或字典。根据您的代码,我认为您假设它始终是字典。所以你可能想添加:

if (![_jsonId isKindOfClass:[NSDictionary class]]) ...

然后你想知道字典里有什么,如果有的话。所以使用objectForKey:。或者,更好的是_jsonId[@"Mon"]。你会得到一个对象,或者你会得到nil

valueForKey: 是一种完全不同的机制,键值编码。它是在NSObject 上定义的,因此由NSDictionary 以及几乎所有其他东西继承。它被定义为引发未知键的异常。由于它引发异常而不是返回结果,因此您尝试比较结果是无效的。

【讨论】:

  • 我明白了。但是如何检查它是否为空?使用 if(_jsonId[@"Mon"] ==nil)?
  • 是的,可以。 objectForKey:[@"Mon"] 将返回一个对象,如果有的话,或者 nil 否则。与valueForKey: 不同,不会引发异常。我已经更新了答案。 (附注:不幸的是,这两种方法的名称相似,并且 NSDictionary 实现了valueForKey:,因此在您突然处理异常之前,错误不会变得明显;混淆两者是更常见的目标之一-我认为 C 混淆)
  • 我已经尝试过这种方法并尝试使用 NSDictionary 中没有对象的键,但程序仍然崩溃,XCode 告诉我 *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因: '*** -[__NSArrayM insertObject:atIndex:]: 对象不能为 nil'
  • @DevArenaCN [NSNull null]nil 不一样,所以也不要再使用它了
  • @trojanfoe 好的,我已经改变了。感谢您的提醒。但是我仍然不能使用 if (_jsonId[@"Sun"]== nil) 来判断密钥是否为空......当我得到一个 nil 密钥时,它仍然可以在它不是 nil 时发挥作用......
【解决方案2】:

我想我明白了。我们来看代码:

if (_jsonId[@"Sun"]== nil) {
    [_keySun addObject:@"No Class For Today"];
    [Monday addObject:[_keySun objectAtIndex:1]];
}
else {
   _keySun = [_jsonId objectForKey:@"Sun"];
    ...

如果存在键“Sun”的对象,则将其存储到 _keySun 中。如果没有对象,则在 _keySun 中不存储任何内容。 _keySun 将为零。您向 _keySun 发送一条 addObject 消息 - 但发送给 nil 对象的任何消息都不会执行任何操作。然后调用 [_keySun objectAtIndex:1]。同样,向 nil 对象发送消息什么也不做,并返回 nil,这就是为什么将 nil 添加到 Monday 对象并导致崩溃的原因。

如果你将 _keySun 设置为一个空的 NSMutableArray,你会因为另一个原因而崩溃:你尝试添加 one 对象。您可以使用 objectAtIndex:0 读取该对象。但是要读取 objectAtIndex:1 您需要数组中的 两个 对象。

顺便说一句。如果您正在读取的 JSON 文档包含显式 null,您将从 JSON 解析器获得 [NSNull null]。因此,如果您的 JSON 包含 "Sun": null 那么 objectForKey:@"Sun" 将给出 [NSNull null]。如果您的 JSON 根本不包含键“Sun”,则 objectForKey:@"Sun" 将给出 nil。

【讨论】:

  • 是的,我现在看到了。谢谢你的回答。仔细想想,这确实是问题所在。再次感谢您
猜你喜欢
  • 2011-07-17
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 2016-01-20
  • 2015-12-06
  • 1970-01-01
  • 2014-05-14
  • 2011-08-23
相关资源
最近更新 更多