Objective-C是否使用短路评估?

时间:2010-01-13 22:23:49

标签: objective-c short-circuiting

我尝试了以下几点:

if(myString != nil && myString.length) { ... }

得到了:

- [NSNull length]:发送到实例的无法识别的选择器

第一个条件失败后,Objective-C不会短路吗?

4 个答案:

答案 0 :(得分:30)

Objective-C支持短路评估,就像C一样。

在您的示例中myString似乎是NSNull而不是nil,因此myString != nil是真的。

NSNull是一个单例,用于表示只允许对象的nil,例如在NSArray中。

通常,人们写if (!myString && myString.length == 0)。与nil相比非常难看。另外,我将长度与0进行比较。这似乎更清楚。

答案 1 :(得分:10)

Objective-C是C的严格超集。

因为C支持短路评估,所以Objective-C也可以。

答案 2 :(得分:3)

NSNull定义为什么?如果它是一个应该代表什么的对象,那么它就不会是零。换句话说,NSNull和nil不一样。

答案 3 :(得分:0)

如果你有某个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