6

在Objective-C中,与C中的id完全一样void *吗?(通用指针类型)。

如果是这样,当我们使用

id obj = [[Fraction alloc] init];
[obj methodName];
obj = [[ComplexNumber alloc] init];
[obj anotherMethodName];

当方法被调用时,程序通过什么方式知道什么是类obj

4

3 回答 3

5

id与 a 不一样void *id是一个指向未知类型的 Objective C 对象的指针;像objectC# 或 Java 的数据类型。Avoid*可以指向任何东西;非 nilid应指向所有 ObjC 对象共有的数据结构,并包含指向其各自类数据的指针。

ObjC 运行时-//etc 的alloc实现init。- 确保所有有效对象中都有正确的类指针。

IIRC,在 Apple 的实现中,指向的指针大小的变量实际上id指向类的指针。

在类的数据块中,有一个方法列表,将方法签名映射到指向方法实现的函数指针。从那里开始,这是一个相当简单的查找,当您向对象发送消息(即调用其中的方法)时,它会在运行时发生。还有一个指向基类的指针,以便方法查找可以继续沿继承树向上。

顺便说一句,这就是为什么取消引用 void 指针是编译器错误,而将消息发送到 anid是合法的,如果静态不安全的话。

于 2012-04-23T01:55:10.527 回答
5

idObjective-C 中的内容与 C 中的内容不同void *

来自 Apple 的“The Objective-C Programming Language”:

typedef struct objc_object {
   Class isa;
} *id;

这意味着,id是一个指向objc_object结构的指针,它不同于指向void.

因此,每个对象都有一个isa变量,告诉它它是什么类的实例。由于Class类型本身被声明为指针。

typedef struct objc_class *Class;

关于,程序如何在方法调用期间告诉类?,这是来自上面引用的同一编程指南:

isa实例变量标识对象的类——它是什么类型的对象。具有相同行为(方法)和相同类型数据(实例变量)的对象是同一类的成员。

因此,对象在运行时是动态类型的。无论何时需要,运行时系统都可以通过询问对象来找到对象所属的确切类。(要了解有关运行时的更多信息,请参阅 Objective-C 运行时编程指南。

根据指南,idObjective nil-C 的 、 和其他基本类型都在头文件中定义objc/objc.h

于 2012-04-23T02:29:02.630 回答
1

是的,id只是一个通用指针。编译时的类解析只是为了通知用户警告和错误。但是,具有 id 类型的名副其实在编译时不会绑定到任何特定的类。在运行时访问对象之前,不会知道实际的类。如果对象是 的子类NSObject,它很可能是,您的代码可以询问对象它的类是什么。

[myObject class]将返回myObject. [myObject isMemberOfClass:[SomeClass class]]将返回一个BOOL指示更白的 ir 不是myObject该类的成员SomeClass

如果您的代码调用 上的方法myObject,运行时将尝试进行调用,即使对象没有响应该方法。如果myObject不实现该方法,则会发生运行时异常。

您也可以myObject提前询问该方法是否适用于[myObject respondsToSelector:@selector(myCoolMethod)].

于 2012-04-23T01:43:10.477 回答