字符串isNullOrEmpty作为类别

Ech*_*lon 2 iphone null objective-c ios objective-c-category

我正在尝试创建一个检查null/nil/empty字符串的方法,并且我试图让它作为一个类别工作,但没有运气.

我正在使用此代码,基于本主题中的答案:

@implementation NSString (NSStringExtension)
- (BOOL)isNullOrEmpty {
    return self == nil || 
    self == (id)[NSNull null] ||
    [@"" isEqualToString:self] || 
    [[self stringByReplacingOccurrencesOfString:@" " withString:@""] length] == 0||
    [self isEqualToString:@"(null)"]
     || ([self respondsToSelector:@selector(length)] && [(NSData *) self length] == 0)
     || ([self respondsToSelector:@selector(count)] && [(NSArray *) self count] == 0)
     || [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0;
}
@end
Run Code Online (Sandbox Code Playgroud)

然而,当我尝试使用它时,这就是我得到的:

NSLog([@"" isNullOrEmpty] ? @"1":@"0"); // prints 1
NSString *s1 = nil;
NSLog([s1 isNullOrEmpty] ? @"1":@"0"); // prints 0
NSLog([args.itemName isNullOrEmpty] ? @"1":@"0"); // prints 0
NSLog([(NSString*)nil isNullOrEmpty] ? @"1":@"0"); // prints 0
Run Code Online (Sandbox Code Playgroud)

这让我感到困惑,我只能假设iOS5/ARC的某些组合导致nil对象被强制转换为空白字符串/指针.调试器将字符串显示为0x0,但是当我使用我的isNullOrEmpty方法时,我得到了错误.

Jos*_*ell 5

return self == nil
Run Code Online (Sandbox Code Playgroud)

这永远不会发生.如果您尝试发送isNullOrEmpty(或任何其他消息)nil,则不会发生任何事情(objc_msgSend()负责消息调度的函数,检查nil接收器作为其中的第一件事并中止).

self == (id)[NSNull null]
Run Code Online (Sandbox Code Playgroud)

这也永远不会发生.如果您发送isNullOrEmpty的是一个实例的对象,那么NSNull这里的方法就是一个方法NSString,不会被调用.相反,NSNull版本(可能不存在)将是.

同样,([self respondsToSelector:@selector(count)] && [(NSArray *) self count])永远不会发生.如果对象 a NSArray,则isNullOrEmpty永远不会运行,因为,再次,它是一种方法NSString.

相应地,[(NSData *) self length]不会做你认为它做的事情.NSString实例确实响应length,但是将对象转换为NSData不使用NSData方法的版本 - 它仍然以NSString版本的形式结束length,因为对象实际上是一个NSString(只在编译时才进行转换;它不能改变在运行时的任何事情).

[self isEqualToString:@"(null)"]
Run Code Online (Sandbox Code Playgroud)

在这里,你似乎是检查nil一遍,但你正被误导的表示NSLog它打印时选择nil:

NSLog(@"%@", nil);
Run Code Online (Sandbox Code Playgroud)

这将显示(null)在控制台中,但这并不意味着对象本身就是包含这些字符的字符串.NSLog只需选择要显示的字符串nil.*

你们有几个人正在做将要求这是一个类别的东西NSObject,所以该方法在事实上被调用,即使对象是不是一个NSString.

要检查仅由空格组成的字符串,您需要的是@""在修剪空格后与空字符串的比较:

NSString * trimmedSelf = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// Then either:
[trimmedSelf isEqualToString:@""];
// Or:
([trimmedSelf length] == 0);
Run Code Online (Sandbox Code Playgroud)

*甚至更好,做NSLog(@"%@", [NSNull null]);显示<null>(尖括号而不是括号),奇怪地混淆你遇到的前几次NSNull.

  • @Echilon:如果你反转`isNullOrEmpty`的语义,并使它成为`isNotEmpty`,你可以将它简化为`[someString isNotEmpty]`,因为如果`someString`是`nil`,它也会返回0/false /`NO`. (2认同)