如何检查JSON对象是否包含<null>?

3

我在我的应用程序中通过进行网络请求从服务器获取一个Json。在Json对象中,某些键的值为<null>。如果接收到这种类型的响应,则我的应用程序会崩溃。请告诉我如何进行验证?

我已经尝试过这种方法,但并不总是有效。

 if(!(user_post.username==(id)[NSNull null]) )
{

        user_post.username=[dict_user_info objectForKey:@"name"];
         if(user_post.username!=nil)
            {

               ser_post.username=[dict_user_info objectForKey:@"name"];

             }
        else
              {

                user_post.username=@"Username";

              }

}

检查 if ([user_post.username length]>=1) - Fahim Parkar
1
使用isEqual,例如 if([user_post.username isEqual:[NSNull null]])也可以使用isKindOfClass - 0yeoj
在第一行中,我认为你的意思是要测试 [dict_user_info objectForKey:@"name"] 是否为 [NSNull null] - Avi
7个回答

1

考虑对值进行null检测,以防止程序崩溃。就像这样:

if([dict_user_info objectForKey:@"name"] != [NSNull null])
{
    ser_post.username=[dict_user_info objectForKey:@"name"];
}

1
你需要解释为什么你的代码示例比其他人的更好。目前,因缺乏说明,你的答案已被自动标记为低质量。 - nalply

0
创建一个 NSDictionaryCategory,并在其中添加以下方法,该方法将字典中每个键的 null 值替换为空字符串。
- (NSDictionary *)dictionaryByReplacingNullsWithStrings 
{
    const NSMutableDictionary *replaced = [self mutableCopy];
    const id nul = [NSNull null];
    const NSString *blank = @"";

    for(NSString *key in self) {
        const id object = [self objectForKey:key];
        if(object == nul || object == NULL) {
            //pointer comparison is way faster than -isKindOfClass:
            //since [NSNull null] is a singleton, they'll all point to the same
            //location in memory.
            [replaced setObject:blank
                         forKey:key];
        }
    }

    return [replaced copy];
}

用法: [yourJSONDictionary dictionaryByReplacingNullsWithStrings];

在iOS中了解更多关于类别的内容,请参阅Tutorial 1Tutorial 2


0
yourJsonObject = [myDic valueforkey@"key"];
if(yourJsonObject != [NSNull null])
{
 //not null
}
** you can also check whether object exist or not 
if(yourJsonObject)
{
//exist
}

0

我认为你混淆了逻辑。我正在尝试保持代码的真实性,但如果以下内容不是你想要的,请告诉我:

if (dict_user_info[@"name"] != nil && [dict_user_info[@"name"] isKindOfClass:[NSNull class]] == NO) {
    user_post.username = dict_user_info[@"name"];

    if (user_post.username != nil) {
        ser_post.username = user_post.username;
    } else {
        user_post.username = @"Username";
    }
}

0

这是我为我的项目编写的一些方法,请尝试使用:

/*!
 *  @brief  Makes sure the object is not NSNull or NSCFNumber, if YES, converts them to NSString
 *  @discussion Sometimes JSON responses can contain NSNull objects, which does not play well with Obj-C. So when you access a value from a JSON and expect it to be an NSString, pass it through this method just to make sure thats the case.
 *  @param str The object that is supposed to be a string
 *  @return The object cleaned of unacceptable values
 */
+ (NSString *)cleanedJsonString:(id)str
{
  NSString *formattedstr;
  formattedstr = (str == [NSNull null]) ? @"" : str;
  if ([str isKindOfClass:[NSNumber class]]) {
    NSNumber *num = (NSNumber*) str;
    formattedstr = [NSString stringWithFormat:@"%@",num];
  }
  return formattedstr;
}
/*!
 *  @brief  Makes Sure the object is not NSNull
 *  @param obj Sometimes JSON responses can contain NSNull objects, which does not play well with Obj-C. So when you access a value from a JSON ( NSArray, NSDictionary or NSString), pass it through this method just to make sure thats the case.
 *  @return The object cleaned of unacceptable values
 */
+ (id)cleanedObject:(id)obj
{
  return (obj == [NSNull null]) ? nil : obj;
}
/*!
 *  @brief A JSON cleaning function for NSArray Objects.
 *  @discussion Sometimes JSON responses can contain NSNull objects, which does not play well with Obj-C. So when you access a value from a JSON and expect it to be an NSArray, pass it through this method just to make sure thats the case. This method first checks if the object itself is NSNull. If not, then it traverses the array objects and cleans them too.
 *  @param arr The Objects thats supposed to be an NSArray
 *  @return The NSNull Cleaned object
 */
+ (NSArray *)cleanedJsonArray:(id)arr
{
  if (arr == [NSNull null]) {
    return [[NSArray alloc] init];
  }
  else
  {
    NSMutableArray *arrM = [(NSArray*)arr mutableCopy];
    int i=0;
    for (id __strong orb in arrM)
    {
        if (orb == [NSNull null])
        {
            [arrM removeObjectAtIndex:i];;
        }
        i++;
    }
    return arrM;
  }
}

只需将一个 JSON 字符串、数组或对象传递给相应的方法,该方法将为您进行清理。

0

为自己着想,编写一个处理此问题并将其放入扩展中的方法。例如:

- (NSString*)jsonStringForKey:(NSString*)key
{
    id result = self [key];
    if (result == nil || result == [NSNull null]) return nil;
    if ([result isKindOfClass:[NSString class]]) return result; 

    NSLog (@"Key %@: Expected string, got %@", key, result);
    return nil;
}

你甚至可以添加一些代码,接受NSNumber*类型的结果并将它们转换为字符串,如果这是你的服务器返回的内容(有些帖子中有人遇到了这样的问题,他的服务器返回的是像40这样的数字或者"40-42"这样的字符串,这时候这种方法就非常有用)。
然后你的代码就变成了一行可读性很高的代码。
user_post.username = [dict_user_info jsonStringForKey:@"name"] ?: @"username";

实际上,我使用几种略有不同的方法,具体取决于我是否期望为空值、没有值、空字符串或者不确定,这样可以在我的假设错误时给我警告(但总是返回不会出错的内容)。


-2

试试这个:

if(!(user_post.username == (NSString *)[NSNull null]) )

1
[NSNull null]进行强制转换是错误且无用的。它什么也做不了。 - Avi
为什么要用 ! == 代替传统的 !=?@Avi:需要一些强制转换,因为编译器不允许您比较NSString和NSNull。我会转换为id(以避免[NSNull null]可能是NSString的印象)。 - gnasher729
编译器会生成一个警告,但它肯定允许这样做。我同意将其转换为 id 更好。 - Avi
NSString * 强制转换为 NSNull *,这样编译器就不会抱怨 something == [NSNull null] 了。 - Saheb Roy
@Avi 在我的构建中,如果编译器发出警告,它是不允许的 :-) (严格零警告政策)。 - gnasher729

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接