有没有办法在Cocoa上的Objective-C中强制执行运行时类型检查?

时间:2010-01-11 01:50:24

标签: objective-c typechecking enforcement

您好我找到了一种在Cocoa上的Objective-C中强制执行运行时类型检查的方法。

这是我的代码示例。 关于变量'b'的错误赋值,我预计运行时错误。但事实并非如此。编译并执行没有任何错误。

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

 NSArray* a = [NSArray arrayWithObject: @"TEST"]; 
 NSURL* b = [a objectAtIndex:0]; 

    NSLog(@"Is this URL? %i", [b isKindOfClass:NSURL.class]);
    [pool drain];
    return 0;
}

// Console log after program execution:
// 2010-01-11 10:25:02.948 Type Checking[98473:a0f] Is this URL? 0

我很惊讶没有运行时类型检查。因为我使用了所有高级语言,如VB,C#,Java,ActionScript ......我不知道像C这样的低级语言,所以我不能确定这是正确的方法...... 很难弄清楚为什么没有编译或运行时错误。但我开始明白这是真实C世界的自然规律。但更强大的类型检查将帮助我很多。甚至只在调试会话中。有没有办法做到这一点?

如果没有运行时类型检查,我必须使用哪种编码和调试策略来处理错误的类型值?什么是运行时类型检查之间的权衡是什么?

3 个答案:

答案 0 :(得分:2)

嗯,有运行时类型检查,但它发生了一会儿。当您尝试将NSString实例放入NSURL *变量时,我假设您期待某种异常。相反,当您尝试在NSString实例上调用任何特定于NSURL的方法时,您将获得异常。

例如,如果你尝试[b isFileURL],你会得到一个例外,例如“NSString不响应选择器'isFileURL'”。

理解为什么在您的示例中没有编译时类型检查也很重要。具体来说,缺少编译时类型检查是id类型的唯一且重要的属性,这是NSArray的-objectAtIndex:返回的属性。

答案 1 :(得分:1)

Objective-C确实对消息参数和返回类型进行了编译时类型检查,但它比许多其他语言稍微宽松一些。一个主要的区别是像NSArray和NSDictiomary这样的集合类是通用的。您可以将任何类型的对象放入NSArray中 - 元素不必是相同的类型。因此,添加或访问元素时没有类型检查。

没有运行时类型检查变量赋值。我认为这是一个表现捷径。一般来说,这不是一个问题。如果将错误类型的值分配给变量,它最终会收到一条它不理解的消息,这会生成一个非常有用的错误消息。

答案 2 :(得分:0)

当类型错误时,NSObject框架经常会大惊小怪,但您可以手动检查类型并抛出异常:

if (![obj isKindOfClass:SomeObjectClass.class])
  [NSException raise:@"BadTypeException"
    format:@"Bad type at line %d", (int)__LINE__];
[obj xyz];

...

if (![obj conformsToProtocol:@protocol(SomeProtocol)])
  [NSException raise:@"BadTypeException"
    format:@"Bad type at line %d", (int)__LINE__];
[obj abc];

编辑:删除了上一节声明对不存在的方法的调用返回nil或0;正如Mark Bessey所说,如果非零对象没有实现方法,则抛出异常(不返回零)。

相关问题