【问题标题】:What is the right way to check for a null string in Objective-C?在 Objective-C 中检查空字符串的正确方法是什么?
【发布时间】:2009-06-09 08:13:48
【问题描述】:

我在我的 iPhone 应用中使用了这个

if (title == nil) {
    // do something
}

但它会抛出一些异常,并且控制台显示标题为“(null)”。

所以我现在正在使用它:

if (title == nil || [title isKindOfClass:[NSNull class]]) {
    //do something
}

有什么区别,判断一个字符串是否为空的最好方法是什么?

【问题讨论】:

标签: ios objective-c cocoa-touch


【解决方案1】:

正如其他人指出的那样,在 Cocoa/Objective C 下有多种“null”。但要注意的另一件事是 [title isKindOfClass:[NSNull class]] 是毫无意义的复杂,因为 [NSNull null] 已记录在案成为单身人士,因此您可以检查指针是否相等。见Topics for Cocoa: Using Null

所以一个好的测试可能是:

if (title == (id)[NSNull null] || title.length == 0 ) title = @"Something";

请注意如何使用这样一个事实,即使 title 为 nil,title.length 也会返回 0/nil/false,即在这种情况下为 0,因此您不必对它进行特殊处理。这是 Objective C 新手很难适应的东西,尤其是来自其他语言的消息/方法调用 nil 崩溃的语言。

【讨论】:

  • 谢谢!但是我首先问了这个问题,因为我得到了异常,因为“标题”为空。
  • 标题应该是什么类型?例如,如果它是一个 NSString,我会收到以下警告:比较不同的 Objective-C 类型 'struct NSNull *' 和 'struct NSString *' 缺少强制转换 有没有办法删除它(我不知道从那以后事情是否发生了变化有人问过这个问题)?
  • 在不编译的情况下为我提供发布代码的权利;-)。 title 大概是一个 NSString,但不管 title 的类型如何,只需将 null 转换为通用 id 类型:(id)[NSNull null]。
  • @JLT nil 和 [NSNull null] 永远不会相同。 [NSNull null] 是一个单例对象,当不能使用 nil 时(例如在 NSArray 或 NSDictionary 值中),可以用作 nil 的替代对象。所以一个用例可能是你有一个可选字符串的 NSArray,其中一些可能是 null,并且你在数组中使用 [NSNull null] 来处理 null 的情况。在实践中,测试很少需要,只有当您(或您使用的库!)主动使用 [NSNull null] 作为占位符时。
  • 从 Flutter 来到这里,并寻找 Map 项目的值(在 Dart 中为 null)与 Objective C 中的 nilNULL 不对应的原因。原因是它实际上是NUNull null,而不是NULL null。谢谢@PeterNLewis!
【解决方案2】:

就这么简单

if([object length] >0)
{
  // do something
}

请记住,在目标 C 中,如果 object 为 null,则返回 0 作为值。

这会给你一个空字符串和一个长度为 0 的字符串。

【讨论】:

  • 如果对象是 NSNull,这将不起作用,仍然需要先明确检查。
  • 您也可以为 NSNull 创建一个类别,使其返回 0 的长度消息:)
  • 是的,如果对象是 NSNull,这会崩溃。
  • 如果对象等于 NSNull,这将崩溃
  • 除了 NSNull 无法识别的选择器问题之外,这不会区分为 nil 的 NSString 指针或实际存在但本质上为空字符串的 NSString。 (例如作为文字 object = @"";object = nil;
【解决方案3】:

参考本站以下相关文章:

我认为您的错误与其他问题有关,因为您不需要进行额外检查。

另请参阅此相关问题:Proper checking of nil sqlite text column

【讨论】:

  • 令人讨厌的是,我没有足够的“点”来添加第二个超链接(甚至是本网站上的某些内容),另请参阅:-stackoverflow.com/questions/598396/…
  • ...请允许我。虽然您应该能够从代表 0 编辑自己的帖子。
  • 谢谢 - 非常好。当我写我的第一篇文章时,它说新用户只能添加 1 个超链接(这似乎有点苛刻 - 特别是对于本网站中的交叉链接)。
【解决方案4】:

我发现为了真正做到正确,你最终不得不做类似的事情

if ( ( ![myString isEqual:[NSNull null]] ) && ( [myString length] != 0 ) ) {
}

否则你会遇到奇怪的情况,控制仍然会绕过你的检查。我还没有遇到过通过isEqual 和长度检查的。

【讨论】:

    【解决方案5】:

    所有这些“对我有用的答案”是怎么回事?我们都用同一种语言编码,规则是

    1. 确保引用不是nil
    2. 检查并确保字符串的长度不为 0

    这对所有人都有效。如果给定的解决方案只“为您工作”,那只是因为您的应用程序流程不允许引用可能为 null 或字符串长度为 0 的情况。正确的方法是处理方法在所有情况下你想要什么。

    【讨论】:

    • 如果引用是nil(注意:不是“null”),那么发送消息,如length,将产生0(或适当的0-方法的返回类型的值)。 那是语言的规则。在这种情况下,无需单独检查nil
    • 我说 null 仅仅是因为 C++ 的习惯,如果你的代码在 nil 对象上调用方法,那么你的代码很可能被破坏了。您会发现在任何语言中调用 NULL/NIL(相同概念)上的方法通常都是一个坏主意。仅仅因为 obj-c 允许你做这样的事情并不意味着你应该只是传递 nil 对象并试图在不关心的情况下使用它们。
    • 向 nil 发送长度确实会产生 0 - 但是向 NSNull 发送长度会产生异常。
    • @nenchev 没有人说只是传递 nil 对象,但是检查 nil,然后调用一个方法并使用它的返回值比使用像它应该被使用的语言特性并检查更糟糕的是 IMO之后方法返回值的有效性。
    • @Kevin 我不确定它到底有多糟糕,仅仅因为它的语言功能并不意味着它很棒。不检查其 null 是否会打开可能导致更难跟踪运行时错误的代码路径。通常最好验证您的输入是否符合您的预期,如果不是,请做出相应的反应。我个人不喜欢尝试向 nil 对象发送消息时不出现运行时异常的“功能”,因为它通常更容易错过一些运行时错误。
    【解决方案6】:

    如果您想针对所有 nil/空对象(如空字符串或空数组/集合)进行测试,您可以使用以下方法:

    static inline BOOL IsEmpty(id object) {
        return object == nil
            || ([object respondsToSelector:@selector(length)]
            && [(NSData *) object length] == 0)
            || ([object respondsToSelector:@selector(count)]
            && [(NSArray *) object count] == 0);
    }
    

    【讨论】:

    • 这实际上并没有检查可能有意义的 object == [NSNull null]。
    【解决方案7】:

    有两种情况:

    一个对象可能是[NSNull null],也可能是不可能的。
    您的应用程序通常不应该使用[NSNull null];,只有在您想将“null”对象放入数组或将其用作字典值时才使用它。然后您应该知道哪些数组或字典可能包含空值,哪些可能不包含。
    如果您认为数组从不包含 [NSNull null] 值,请不要检查它。如果有[NSNull null],你可能会得到一个异常,但这很好:Objective-C 异常表示编程错误。你有一个编程错误需要通过更改一些代码来修复。

    如果一个对象可能[NSNull null],那么您只需通过测试来检查它
    (object == [NSNull null])。调用isEqual 或检查对象的类是无稽之谈。只有一个 [NSNull null] 对象,普通的旧 C 运算符以最直接和最有效的方式检查它。

    如果你检查了一个不能是[NSNull null]NSString 对象(因为你知道它不能是[NSNull null] 或者因为你刚刚检查了它与[NSNull null] 不同,那么你需要问问自己你想要什么处理一个空字符串,即长度为 0 的字符串。如果将其视为 null 字符串,如 nil,则测试 (object.length == 0)。如果 object == nil,object.length 将返回 0,因此此测试涵盖 nil长度为 0 的对象和字符串。如果将长度为 0 的字符串与 nil 字符串区别对待,只需检查是否为 object == nil

    最后,如果要向数组或字典中添加字符串,并且该字符串可能为 nil,则可以选择不添加,将其替换为 @"",或将其替换为 [NSNull null]。将其替换为@"" 意味着您无法区分“无字符串”和“长度为 0 的字符串”。将其替换为[NSNull null] 意味着您必须在访问检查[NSNull null] 对象的数组或字典时编写代码。

    【讨论】:

    • 很长,但这很好。 NSNull 应该只出现在单例中!这整个问题毫无意义,告诉我编码器没有做正确的事情,而且未来还有更多,没有阅读手册/良好的代码实践
    【解决方案8】:

    你只需检查 nil

    if(data[@"Bonds"]==nil){
      NSLog(@"it is nil");
    }
    

    if ([data[@"Bonds"] isKindOfClass:[NSNull class]]) {
        NSLog(@"it is null");
    }
    

    【讨论】:

      【解决方案9】:

      宏观解决方案(2020 年)

      这是我用于安全字符串的宏,而不是在 UILabel 上获取“(null)”字符串,例如:

      #define SafeString(STRING) ([STRING length] == 0 ? @"" : STRING)
      

      假设你有一个成员类和 name 属性,并且 name 是 nil:

      NSLog(@"%@", member.name); // prints (null) on UILabel
      

      使用宏:

      NSLog(@"%@", SafeString(member.name)); // prints empty string on UILabel
      

      干净整洁?

      扩展解决方案 (2020)

      如果你喜欢在你的项目中检查 nil Null 和空字符串,你可以使用下面的我的扩展行:

      NSString+Extension.h

      ///
      /// Checks if giving String is an empty string or a nil object or a Null.
      /// @param string string value to check.
      ///
      + (BOOL)isNullOrEmpty:(NSString*)string;
      

      NSString+Extension.m

      + (BOOL)isNullOrEmpty:(NSString*)string {
          if (string) { // is not Nil
              NSRange range = [string rangeOfString:string];
              BOOL isEmpty = (range.length <= 0 || [string isEqualToString:@" "]);
              BOOL isNull = string == (id)[NSNull null];
      
              return (isNull || isEmpty);
          }
      
          return YES;
      }
      

      示例用法

      if (![NSString isNullOrEmpty:someTitle]) {
          // You can safely use on a Label or even add in an Array for example. Remember: Arrays don't like the nil values!
      }
      

      【讨论】:

        【解决方案10】:
        if(textfield.text.length == 0){
           //do your desired work
        }
        

        【讨论】:

          【解决方案11】:

          试试这个检查null

           if (text == nil)
          

          【讨论】:

            【解决方案12】:
            @interface NSString (StringFunctions)
            - (BOOL) hasCharacters;
            @end
            
            @implementation NSString (StringFunctions)
            - (BOOL) hasCharacters {
                if(self == (id)[NSNull null]) {
                    return NO;
                }else {
                    if([self length] == 0) {
                        return NO;
                    }
                }
                return YES;
            }
            @end
            
            NSString *strOne = nil;
            if([strOne hasCharacters]) {
                NSLog(@"%@",strOne);
            }else {
                NSLog(@"String is Empty");
            }
            

            这适用于以下情况,NSString *strOne = @"" OR NSString *strOne = @"StackOverflow" OR NSString *strOne = [NSNull null] OR NSString *strOne

            【讨论】:

              【解决方案13】:

              如果这种东西不存在,你可以创建一个 NSString 类别:

              @interface NSString (TrucBiduleChoseAdditions)
              
              - (BOOL)isEmpty;
              
              @end
              
              @implementation NSString (TrucBiduleChoseAdditions)
              
              - (BOOL)isEmpty {
                  return self == nil || [@"" isEqualToString:self];
              }
              
              @end
              

              【讨论】:

              • 这可能是矫枉过正,我不认为它会解决这个问题。
              • self == nil 是没有意义的——如果 self 是 nil,Objective C 一开始就不会打电话给你。 [(NSString*)nil isEmpty] 将简单地返回 0/nil/false 而无需调用您的代码。
              • 实际上,除此之外,[(NSString*)nil isEmpty] 将返回 false。在编写此类Objective C方法时,最好将它们定义为使nil的0/nil/false有意义,因此将方法编写为hasCharacters会更好。请注意,长度已经适用于此,因为您可以在任何想要使用 if (!s.isEmpty) 的地方使用 if (s.length),并且对于 s == nil 情况,s.length 将正确返回 0。
              • 这是一次严重的崩溃。您为 NSString 实现了“isEmpty”,但如果它实际上是 NSNull,那么 isEmpty 将被发送到 NSNull,并且由于它不响应该消息而崩溃!
              【解决方案14】:

              对我有用的是if ( !myobject )

              【讨论】:

              • 这不适用于 null 对象,仅适用于 nil 对象。例如...NSArray *testarray = [NSArray arrayWithObjects:[NSNull null],@"", nil]; NSString *string = [testarray objectAtIndex:0]; NSLog(@"null string value: %@",string); if (!string) { NSLog(@"string evaluates to null"); } if (string &amp;&amp; (string==(id)[NSNull null])) { NSLog(@"string does not evaluate to null"); }
              • Err.. 对格式表示抱歉,但代码会编译 :)
              【解决方案15】:

              对字符串的空值条件的完整检查可以如下:

              如果(我的字符串) { if([mystring isEqualToString:@""]) { mystring=@"一些字符串"; } } 别的 { //语句 }

              【讨论】:

                【解决方案16】:

                我只检查空字符串

                if ([myString isEqual:[NSNull null]])

                【讨论】:

                  【解决方案17】:
                  if ([linkedStr isEqual:(id)[NSNull null]])
                                  {
                                      _linkedinLbl.text=@"No";
                                  }else{
                                      _linkedinLbl.text=@"Yes";
                                  }
                  

                  【讨论】:

                  • 虽然这段代码 sn-p 可以回答这个问题,但它没有提供任何上下文来解释如何或为什么。考虑添加一两句话来解释你的答案。
                  【解决方案18】:
                  if ([strpass isEqual:[NSNull null]] || strpass==nil || [strpass isEqualToString:@"<null>"] || [strpass isEqualToString:@"(null)"] || strpass.length==0 || [strpass isEqualToString:@""])
                  {
                      //string is blank  
                  }
                  

                  【讨论】:

                    【解决方案19】:

                    对于字符串:

                    + (BOOL) checkStringIsNotEmpty:(NSString*)string {
                    if (string == nil || string.length == 0) return NO;
                    return YES;
                    

                    }

                    参考下图:

                    【讨论】:

                      【解决方案20】:

                      对于字符串:

                      + (BOOL) checkStringIsNotEmpty:(NSString*)string {
                      if (string == nil || string.length == 0) return NO;
                      return YES;}
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2022-11-14
                        • 1970-01-01
                        • 2022-08-07
                        • 2018-09-01
                        • 2012-04-05
                        • 2014-08-26
                        • 1970-01-01
                        相关资源
                        最近更新 更多