首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >String isNullOrEmpty作为类别

String isNullOrEmpty作为类别
EN

Stack Overflow用户
提问于 2012-03-15 03:57:31
回答 9查看 3.3K关注 0票数 2

我试图创建一个检查null/nil/空字符串的方法,我试图让它作为一个类别工作,但没有成功。

我使用这段代码,基于this topic中的答案

代码语言:javascript
复制
@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

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

代码语言:javascript
复制
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

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

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2012-03-15 04:13:49

代码语言:javascript
复制
return self == nil

这是永远不会发生的。如果您尝试向nil发送isNullOrEmpty (或任何其他消息),则不会发生任何事情(负责消息分派的函数objc_msgSend()首先检查nil接收器,然后中止)。

代码语言:javascript
复制
self == (id)[NSNull null]

这也永远不会发生。如果将isNullOrEmpty发送给作为NSNull实例的对象,则不会调用此处的方法,该方法是NSString上的方法。取而代之的是NSNull的版本(可能不存在)。

同样,([self respondsToSelector:@selector(count)] && [(NSArray *) self count])也永远不会发生。如果对象是一个NSArray,那么isNullOrEmpty将永远不会运行,因为它是NSString的一个方法。

相应地,[(NSData *) self length]并不做您认为它做的事情。NSString实例确实会响应length,但是将对象强制转换为NSData并不使用该方法的NSData版本--它最终仍然是lengthNSString版本,因为该对象实际上是一个NSString (强制转换只在编译时发生;它不能在运行时更改任何内容)。

代码语言:javascript
复制
[self isEqualToString:@"(null)"]

在这里,您似乎再次检查了nil,但您被NSLog在打印nil时选择的表示形式所误导

代码语言:javascript
复制
NSLog(@"%@", nil);

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

您正在做的几件事需要它位于NSObject上的一个类别中,这样即使对象不是NSString,该方法实际上也会被调用。

要检查只包含空格的字符串,您只需在修剪空格之后与空字符串@""进行比较:

代码语言:javascript
复制
NSString * trimmedSelf = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// Then either:
[trimmedSelf isEqualToString:@""];
// Or:
([trimmedSelf length] == 0);

*甚至更好的是,执行NSLog(@"%@", [NSNull null]);会显示<null> (尖括号而不是圆括号),这会让你遇到NSNull的前几次非常困惑。

票数 5
EN

Stack Overflow用户

发布于 2012-03-15 14:37:48

另一种方法是定义一个简单的宏。

代码语言:javascript
复制
#define NSStringIsNullOrEmpty(str) ((str==nil) || [(str) isEqualToString:@""])

这是简单而有效的。如果您不喜欢宏,则始终可以将其转换为函数调用,而不会影响代码的其余部分。

--更新:

@Bryan提出了一个很好的观点。内联函数是一种很好的方法。下面是一个更新宏,它只对str求值一次。

代码语言:javascript
复制
#define NSStringIsNullOrEmpty(str) ({ NSString *_str=(str); ((tmp==nil) || [tmp isEqualToString:@""]);})
票数 1
EN

Stack Overflow用户

发布于 2012-03-15 04:04:40

在Objective-C中,向nil发送消息将始终返回0(或NO、置零结构、NULL等,具体取决于声明的返回类型)。当您将isNullOrEmpty发送到nil时,您编写的isNullOrEmpty方法实际上不会被调用。有关详细信息,请参阅Sending a message to nil?的接受答案。

也许您可以将您的方法更改为isNotNullOrEmpty。那么在向nil发送isNotNullOrEmpty时,返回值0就有意义了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9709304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档