无法弄清楚这种动态打字的事情

时间:2011-10-05 16:17:42

标签: objective-c cocoa dynamic-typing

我正在为面试成为Cocoa开发人员的人提供面试问题列表。我是程序员,但我从未做过Objective-C。我偶然发现了涉及动态打字的interesting question。它应该是基本的,我已经尝试并编译它,但我仍然不确定它是如何以及为什么它起作用。

问题是

  

执行以下操作时,在编译时和运行时会发生什么:

NSString *s = [NSNumber numberWithInt:3];
int i = [s intValue];

在调试器中我得到了

i = (int) 3
s = (__NSFCNumber*) 0x383 (invalid address)

NSLog(@"%d",i)的输出为3NSLog(@"%@",s)的输出为3

有人可以解释一下编译器和运行时系统如何处理所有这些问题,同时也要记住我是Objective-C和Cocoa的新手,但对计算机来说并不是新手。科学?

3 个答案:

答案 0 :(得分:3)

你的s只是一个标准的C指针,指向NSNumber对象(指向a的指针)。

NSNumber以及NSString会回复intValue。就是这样。

答案 1 :(得分:3)

s是一个指针,您声明它将指向NSString个对象。它可以指向任何东西,但理想情况下它应该指向NSString。但是,代码示例的s指向NSNumber对象。

只要你只向s发送方法,NSNumber响应一切的方法都很好(除了编译器警告之外)。如果您尝试将NSString方法发送到s指向的对象,NSNumber没有响应,则会出现异常。如果对象具有匹配的选择器签名(即:@selector(intValue)),则将调用该方法。

答案 2 :(得分:3)

变量“s”的NSString声明只是为了帮助编译器解释变量“s”的意图。它允许编译器在您打算使用某种类型的变量但意外地分配了不同类型的变量的情况下强制执行静态类型检查。在ObjC中,变量可以指向任何对象,而括号语法是向对象发送“消息”的方式。发送消息指示编译器生成查找实现消息的函数的代码。在ObjectiveC中,消息也称为选择器。 (较低级别的细节稍微涉及较多,但它的工作方式很高。)这是动态类型的动态部分,也称为“鸭子打字”。这个想法是,如果它看起来像一只鸭子你应该能像鸭子一样嘎嘎叫。实质上,任何跟随某个形状的对象都可以分配给适合该形状的类型。

请考虑以下事项:

Dog *myPuppy = [[Cat alloc] init] autorelease];
[myPuppy walk];
Food *preparedDish = [self prepareMealForPet];
[myPuppy eat: preparedDish];

编译器会在这里标记你,表示你打算花时间与狗,但实际上是在处理一只猫。然而,它完全有效,因为猫的形状类似于狗,因为它们都可以走路并吃准备好的饭菜。鸭子打字可以让你逃避这一点,因为在很多情况下你需要接受事先不知道的变量类型。此外,通过内省,您可以在运行时发现对象的形状。如果我们想要让我们的小狗吠叫,请考虑上面的代码。我们会得到一个例外,应用程序会崩溃。但是我们可以使用内省来询问我们的对象是否响应“bark”消息以避免崩溃。

if([myPuppy respondsToSelector:@selector(bark)]) {
   [myPuppy bark];
}