在调用 intvalue 之前对字典对象进行 null 检查仍然会导致对 null 对象进行 intvalue 调用

null check for dictionary object before call to intvalue still leads to intvalue calls on null object

我从 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"])

但这也会导致同样的 error/app 崩溃。我的语法似乎与 SO (Check if key exists in NSDictionary is null or not) 上接受的答案一致。关于 else/how 还有什么建议我应该检查是否存在用于应用 intvalue 的键值对?

感谢您的任何建议。

在您的代码中保持连续。不要 运行 使用方法。最好添加更多空检查和类型检查,尤其是在使用 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];
      }
    }
  }
} 

现在代码更安全了。它还会崩溃吗?

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 问题的答案

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

当您在可空字典中调用 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;

}