我试图创建一个检查null/nil/空字符串的方法,我试图让它作为一个类别工作,但没有成功。
我使用这段代码,基于this topic中的答案
@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然而,当我尝试使用这个的时候,我得到的是:
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。
发布于 2012-03-15 04:13:49
return self == nil这是永远不会发生的。如果您尝试向nil发送isNullOrEmpty (或任何其他消息),则不会发生任何事情(负责消息分派的函数objc_msgSend()首先检查nil接收器,然后中止)。
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版本--它最终仍然是length的NSString版本,因为该对象实际上是一个NSString (强制转换只在编译时发生;它不能在运行时更改任何内容)。
[self isEqualToString:@"(null)"]在这里,您似乎再次检查了nil,但您被NSLog在打印nil时选择的表示形式所误导
NSLog(@"%@", nil);这将在控制台中显示(null),但这并不意味着对象本身就是一个包含这些字符的字符串。NSLog只是选择要为nil.*显示的字符串
您正在做的几件事需要它位于NSObject上的一个类别中,这样即使对象不是NSString,该方法实际上也会被调用。
要检查只包含空格的字符串,您只需在修剪空格之后与空字符串@""进行比较:
NSString * trimmedSelf = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// Then either:
[trimmedSelf isEqualToString:@""];
// Or:
([trimmedSelf length] == 0);*甚至更好的是,执行NSLog(@"%@", [NSNull null]);会显示<null> (尖括号而不是圆括号),这会让你遇到NSNull的前几次非常困惑。
发布于 2012-03-15 14:37:48
另一种方法是定义一个简单的宏。
#define NSStringIsNullOrEmpty(str) ((str==nil) || [(str) isEqualToString:@""])这是简单而有效的。如果您不喜欢宏,则始终可以将其转换为函数调用,而不会影响代码的其余部分。
--更新:
@Bryan提出了一个很好的观点。内联函数是一种很好的方法。下面是一个更新宏,它只对str求值一次。
#define NSStringIsNullOrEmpty(str) ({ NSString *_str=(str); ((tmp==nil) || [tmp isEqualToString:@""]);})发布于 2012-03-15 04:04:40
在Objective-C中,向nil发送消息将始终返回0(或NO、置零结构、NULL等,具体取决于声明的返回类型)。当您将isNullOrEmpty发送到nil时,您编写的isNullOrEmpty方法实际上不会被调用。有关详细信息,请参阅Sending a message to nil?的接受答案。
也许您可以将您的方法更改为isNotNullOrEmpty。那么在向nil发送isNotNullOrEmpty时,返回值0就有意义了。
https://stackoverflow.com/questions/9709304
复制相似问题