【问题标题】:null check for dictionary object before call to intvalue still leads to intvalue calls on null object在调用 intvalue 之前对字典对象进行 null 检查仍然会导致对 null 对象的 intvalue 调用
【发布时间】:2015-01-21 10:19:00
【问题描述】:

我从 web 服务器读取 json 得到一个字典数组,并使用以下内容确保在获取数组的第一个字典中的特定键之前获得它的 int 值:

             if([jsonObject[0] objectForKey:@"votes"]!= nil)
             {
             int votes = [[jsonObject[0] objectForKey:@"votes"] intValue];
             [[UserObject userUnique] updateVotes:votes];
             }                 

但是,我的应用程序仍然偶尔会崩溃,说我在 Null 上调用了 intValue。我也尝试将控制语句构造为

if([jsonObject[0] objectForKey:@"votes"])

但这也会导致相同的错误/应用程序崩溃。我的语法似乎与 SO (Check if key exists in NSDictionary is null or not) 上接受的答案一致。关于其他什么/我应该如何检查键值对的存在以应用 intvalue 的任何建议?

感谢您的建议。

【问题讨论】:

  • 您在字典中为“投票”存储什么类型的对象? NSNumber?
  • @Fonix 这是一个 NSString
  • 请发布完整的错误信息。有没有提到NSNull
  • @GuillaumeAlgis 我会发布完整的错误,但我无法按需生成它。它确实提到了 NSNull。我正在尝试 Jeffery Thomas 在下面的回答,并将更新以说明这是否有效。

标签: objective-c dictionary


【解决方案1】:

nilnull 之间存在差异。 nil 不是一个对象:它是一个特殊的指针值。 null(由 [NSNull null] 重新调整)是一个对象:它是必需的,因为它可以存储在像 NSDictionary 这样的容器中。

NSString *votesString = [jsonObject[0] objectForKey:@"votes"];
if (votesString != nil && votesString != [NSNull null])
{
    int votes = [votesString intValue];
    [[UserObject userUnique] updateVotes:votes];
}

编辑:@SunnysideProductions 问题的答案

您提到的帖子推荐了一种通过创建-safeObjectForKey: 方法将null 值转换为nil 值的方法。你没有使用-safeObjectForKey:,你使用的是默认的-objectForKey:方法。

【讨论】:

  • 这是有道理的。我会试试这个,但它与我提到的 SO 帖子相矛盾。
  • @SunnysideProductions 不,它没有。 nilobjectForKey: 返回,当字典对传递的键具有 no 值时。 [NSNull null] 是一个可以存储在 NSDictionary 中的对象,例如表示一个空值。特别是,在 JSON 中,获取 nil 意味着 JSON 对象没有这样的密钥,但获取 NSNull 意味着 JSON 对象拥有与 null 值相关联的密钥(例如,{"myKey": null}) . See this question
【解决方案2】:

在您的代码中保持连续。不要使用方法运行。最好添加更多的空值和类型检查,特别是在使用 json 时。让我们开始吧:

if (jsonObject && [jsonObject isKindOfClass:[NSArray class]])
{
  NSArray *jsonArray=(NSArray *)jsonObject;
  if (jsonArray.count>0)
  {
    id firstObject=jsonArray[0];
    if ([firstObject isKindOfClass:[NSDictionary class]])
    {
      NSDictionary *jsonDict=(NSDictionary *)firstObject;
      id votesNumber=jsonDict[@"votes"];
      if (votesNumber && [votesNumber isKindOfClass:[NSNumber class]])
      {
        int votes=[votesNumber intValue];
        [[UserObject userUnique] updateVotes:votes];
      }
    }
  }
} 

现在代码更安全了。它仍然崩溃吗?

【讨论】:

  • 我会试试这个,几个小时后告诉你。有时需要一段时间才能让它崩溃。
  • 附注当您说“不要使用方法运行”时,这是否意味着在未确认对象类的情况下不要调用对象上的方法?还是你的意思是别的?
【解决方案3】:

当您在可空字典中调用objectForKey时,应用程序崩溃了,所以我通过以下方式解决了这个问题。

- (instancetype)initWithDictionary:(NSDictionary*)dictionary {
id object = dictionary;

if (dictionary && (object != [NSNull null])) {
    self.name = [dictionary objectForKey:@"name"];
    self.age = [dictionary objectForKey:@"age"];
}
return self;

}

【讨论】:

    猜你喜欢
    • 2018-08-13
    • 1970-01-01
    • 2013-11-03
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多