我试图沿着线的东西:Objective-C是否使用短路评估?
if(myString != nil && myString.length) { ... }
,并得到:
- [NSNull长]:发送到实例无法识别选择
是否Objective-C的不短路后的第一个条件失败?
我试图沿着线的东西:Objective-C是否使用短路评估?
if(myString != nil && myString.length) { ... }
,并得到:
- [NSNull长]:发送到实例无法识别选择
是否Objective-C的不短路后的第一个条件失败?
的Objective-C不支持短路评价,就像C.
看来,在你的榜样myString
是NSNull
而不是nil
,因此myString != nil
是真实的。
NSNull是一个单例,用于表示只允许对象的nil
,例如在NSArray中。
顺便说一句,通常,人们写if (!myString && myString.length == 0)
。相比nil
是相当难看的。另外,我会将长度与0进行比较。这似乎更清楚。
Objective-C中是C.
的严格的超由于C支持短路评价,Objective-C的不为好。
NString * str = expressionThatReturnsStrOrNil()|| @ “”;不起作用。这是短路评估不起作用。 – 2012-09-12 11:51:36
@PedroMorteRolo:当然可以。你期望什么结果? (请记住'||'运算符的结果不是'1'或'0',绝不是其他)。 – 2012-09-12 12:02:13
你说得对。我错误地认为C具有与Ruby相同的语义。 – 2012-09-13 09:03:38
什么是NSNull定义为?如果它是一个本不应该代表什么的对象,那它就不会是零。换句话说,NSNull和nil是不一样的。
如果你有一个NSNull的地方,你可能使用JSON解析器或CoreData。当没有设置CoreData中的数字时,CoreData会让你回到NSNull - 对于CoreData中的NSString值也可能是相同的。
同样,你可以在从服务器返回的JSON中有空元素,一些解析器会给你作为一个NSNull对象。所以在这两种情况下,当你使用值时你必须小心,因为你认为是NSString或NSNumber对象的东西实际上是NSNull。
一个解决方案是在NSNull上定义一个类别,它仅仅忽略发送给该对象的所有不理解的消息,如下面的代码所示。然后你的代码会工作,因为NSNull.length将返回0.你可以在你的项目.pch文件中包含类似这样的东西,它将被包含在项目中的每个文件中。
// NSNull+IgnoreMessages.h
@interface NSNull(IgnoreMessages)
- (void)forwardInvocation:(NSInvocation *)anInvocation;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
@end
//NSNull+IgnoreMessages.m
#import "NSNull+IgnoreMessages.h"
@implementation NSNull(IgnoreMessages)
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
if ([self respondsToSelector:[anInvocation selector]])
[anInvocation invokeWithTarget:self];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
NSMethodSignature *sig=[[NSNull class] instanceMethodSignatureForSelector:aSelector];
// Just return some meaningless signature
if(sig==nil)
sig=[NSMethodSignature signatureWithObjCTypes:"@^v^c"];
return sig;
}
@end
这只是等待失败。知道何时处理'NSNull'而不是'nil'很重要,你的代码使得这种情况不太可能发生。在问题的例子中,有一个错误信息包含'NSNull',你不会在你的代码中看到这个错误信息,并且'if(myString)'仍然会评估为true。 – 2010-01-14 11:09:54
那么告诉我,如果你可以发送任何消息给它,它就像nil一样会失败,它仍然会调用NSNull(包括所有的NSObject方法)实际理解的任何消息。 现在它可能会导致错误,因为如果你明确地检查等于零,这将是不正确的。但在大多数编码中,完全是因为nil可以发送任何消息,我只是在类似于(myString.length> 0)的情况下进行测试,在这里可以正常工作。事实上,当一个NSNull滑入你不期望的地方时,这段代码将会阻止你的代码崩溃,所以平衡它是一个稳定增益。 – 2010-01-14 15:41:13
另外,它说的是一个错误消息?这甚至没有任何意义,为什么任何想发回错误消息的地方都会发送NSNull来代替NSString?在实践中,我只见过NSNull从CoreData和一些JSON解析器中走出来,这种测试除了防止非明显的运行时错误外什么都不做。你仍然可以检查NSNull的重要位置。 – 2010-01-14 15:45:34
'NSNull'等于'nil'吗? – 2010-01-13 22:28:56
不是。 NSNull和零不是一回事。一点也不。 – bbum 2010-01-13 22:47:58