【问题标题】:Checking a null value in Objective-C that has been returned from a JSON string检查从 JSON 字符串返回的 Objective-C 中的空值
【发布时间】:2011-06-17 21:11:58
【问题描述】:

我有一个来自网络服务器的 JSON 对象。

日志是这样的:

{          
   "status":"success",
   "UserID":15,
   "Name":"John",
   "DisplayName":"John",
   "Surname":"Smith",
   "Email":"email",
   "Telephone":null,
   "FullAccount":"true"
}

请注意,如果用户不输入,电话将作为 null 输入。

当将此值分配给NSString 时,在NSLog 中它会以<null> 的形式出现

我正在分配这样的字符串:

NSString *tel = [jsonDictionary valueForKey:@"Telephone"];

检查<null> 值的正确方法是什么?它阻止我保存NSDictionary

我尝试过使用条件[myString length]myString == nilmyString == NULL

另外,iOS 文档中的最佳阅读位置在哪里?

【问题讨论】:

    标签: ios objective-c json


    【解决方案1】:

    <null> 是 NSNull 单例日志的方式。所以:

    if (tel == (id)[NSNull null]) {
        // tel is null
    }
    

    (单例存在是因为您不能将nil 添加到集合类中。)

    【讨论】:

    • 如果你想不用演员也可以试试:if ([tel isKindOfClass:[NSNull class]])
    • 我们可以使用: if (object isEqual:[NSNull null]) {--logic here-- }
    【解决方案2】:

    下面是演员表的例子:

    if (tel == (NSString *)[NSNull null])
    {
       // do logic here
    }
    

    【讨论】:

    • or if (tel == (NSString *)NSNull.null) { // 在这里做逻辑 }
    【解决方案3】:

    你也可以像这样检查这个传入的字符串:-

    if(tel==(id) [NSNull null] || [tel length]==0 || [tel isEqualToString:@""])
    {
        NSlog(@"Print check log");
    }
    else
    {  
    
        NSlog(@Printcheck log %@",tel);  
    
    }
    

    【讨论】:

    • 您的第一行NSLog 不正确......它应该说字符串 is 为空。在那种情况下你为什么要打印它?
    • 感谢您的建议,我打印 NSLog 只是为了知道哪个条件变为真
    【解决方案4】:

    如果您正在处理“不稳定”的 API,您可能需要遍历所有键以检查是否为空。我创建了一个类别来处理这个问题:

    @interface NSDictionary (Safe)
    -(NSDictionary *)removeNullValues;
    @end
    
    @implementation NSDictionary (Safe)
    
    -(NSDictionary *)removeNullValues
    {
        NSMutableDictionary *mutDictionary = [self mutableCopy];
        NSMutableArray *keysToDelete = [NSMutableArray array];
        [mutDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
            if (obj == [NSNull null]) 
            {
                [keysToDelete addObject:key];
            }
        }];
        [mutDictinary removeObjectsForKeys:keysToDelete];
        return [mutDictinary copy];
    }
    @end
    

    【讨论】:

      【解决方案5】:

      最佳答案是 Aaron Hayman 在已接受答案下方的评论:

      if ([tel isKindOfClass:[NSNull class]])
      

      它不会产生警告:)

      【讨论】:

        【解决方案6】:

        如果json中有很多属性,使用if语句一一查看比较麻烦。更糟糕的是,代码会很丑陋且难以维护。

        我认为更好的方法是创建一个NSDictionary 类别:

        // NSDictionary+AwesomeDictionary.h
        
        #import <Foundation/Foundation.h>
        
        @interface NSDictionary (AwesomeDictionary)
        - (id)validatedValueForKey:(NSString *)key;
        @end
        
        // NSDictionary+AwesomeDictionary.m
        
        #import "NSDictionary+AwesomeDictionary.h"
        
        @implementation NSDictionary (AwesomeDictionary)
        - (id)validatedValueForKey:(NSString *)key {
            id value = [self valueForKey:key];
            if (value == [NSNull null]) {
                value = nil;
            }
            return value;
        }
        @end
        

        导入此分类后,您可以:

        [json validatedValueForKey:key];
        

        【讨论】:

          【解决方案7】:

          我通常这样做:

          Assuma 我有一个用户数据模型,它有一个名为 email 的 NSString 属性,从 JSON 字典中获取。如果在应用程序内部使用了电子邮件字段,将其转换为空字符串可以防止可能的崩溃:

          - (id)initWithJSONDictionary:(NSDictionary *)dictionary{
          
              //Initializer, other properties etc...
          
              id usersmail = [[dictionary objectForKey:@"email"] copy];
              _email = ( usersmail && usersmail != (id)[NSNull null] )? [usersmail copy] : [[NSString      alloc]initWithString:@""];
          }
          

          【讨论】:

            【解决方案8】:

            在 Swift 中你可以这样做:

            let value: AnyObject? = xyz.objectForKey("xyz")    
            if value as NSObject == NSNull() {
                // value is null
                }
            

            【讨论】:

            • 问题是关于 Objective-C,而不是 Swift。
            • @JasonMArcher 答案仍然为那些通过谷歌搜索提出问题的人提供了一些价值。毕竟这是一个 4 年前的问题。
            【解决方案9】:

            如果您坚持最佳做法,那就是最好的 - 即使用真实的数据模型来读取 JSON 数据。

            看看 JSONModel - 它很容易使用,它会自动为您将 [NSNUll null] 转换为 * nil * 值,因此您可以像往常一样在 Obj-c 中进行检查:

            if (mymodel.Telephone==nil) {
              //telephone number was not provided, do something here 
            }
            

            查看 JSONModel 的页面:http://www.jsonmodel.com

            这里还有一个创建基于 JSON 的应用程序的简单演练:http://www.touch-code-magazine.com/how-to-make-a-youtube-app-using-mgbox-and-jsonmodel/

            【讨论】:

            • 那个 JSONModel 网站还存在吗?它不是英文的,所以我不能确定,但​​它看起来与 JSON 没有太大关系。
            【解决方案10】:

            我尝试了很多方法,但没有任何效果。 最后这对我有用。

            NSString *usernameValue = [NSString stringWithFormat:@"%@",[[NSUserDefaults standardUserDefaults] valueForKey:@"usernameKey"]];
            
            if ([usernameValue isEqual:@"(null)"])
            {
                 // str is null
            }
            

            【讨论】:

              【解决方案11】:
              if([tel isEqual:[NSNull null]])
              {
                 //do something when value is null
              }
              

              【讨论】:

              • 生成警告:不兼容的指针类型将“NSNull * _Nonnull”发送到“类”类型的参数
              【解决方案12】:

              试试这个:

              if (tel == (NSString *)[NSNull null] || tel.length==0)
              {
                  // do logic here
              }
              

              【讨论】:

                【解决方案13】:

                我用这个:

                #define NULL_TO_NIL(obj) ({ __typeof__ (obj) __obj = (obj); __obj == [NSNull null] ? nil : obj; }) 
                

                【讨论】:

                • 您能指导我们如何在 swift 中实现同样的目标吗?
                • 嗨@AmrAngry,我没有看到你的消息,很快就有一种更好和更复杂的方法来使用所谓的DTO上的可编码协议使用响应JSON对象:hackingwithswift.com/example-code/language/… 然后你可以获取包含所需对象的结构或类,您可以设置编码键,因此变量不必与 JSON 对象中的名称相同。
                【解决方案14】:

                如果我们得到空值,那么我们可以使用下面的代码 sn-p 来检查它。

                 if(![[dictTripData objectForKey:@"mob_no"] isKindOfClass:[NSNull class]])
                      strPsngrMobileNo = [dictTripData objectForKey:@"mobile_number"];
                  else
                           strPsngrMobileNo = @"";
                

                【讨论】:

                  【解决方案15】:

                  在这里你也可以通过检查字符串的长度来做到这一点,即

                  if(tel.length==0)
                  {
                      //do some logic here
                  }
                  

                  【讨论】:

                  • 不,如果telNSNull 的一个实例,这将引发异常。
                  • 是的,我认为我们还必须检查它是否为空。我们还必须考虑上述条件
                  猜你喜欢
                  • 1970-01-01
                  • 2022-09-27
                  • 1970-01-01
                  • 2013-10-21
                  • 2018-03-24
                  • 2013-10-24
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多