我知道您使用 [ ] 向对象发送消息,然后将objc_msgSend()
其转换为需要指向对象的指针作为其第一个参数,第二个参数需要一个选择器。
但是像
[myClass doSomething];
It is not a pointer to object 这样的消息传递类呢,那么它是如何工作的呢?
我知道您使用 [ ] 向对象发送消息,然后将objc_msgSend()
其转换为需要指向对象的指针作为其第一个参数,第二个参数需要一个选择器。
但是像
[myClass doSomething];
It is not a pointer to object 这样的消息传递类呢,那么它是如何工作的呢?
实际上,当您向类发送消息时,您实际上是将该消息发送到类对象,该类对象的行为与任何其他对象一样,但有一些限制。
来自苹果的参考:
在 Objective-C 中,一个类本身就是一个对象,它具有一种称为 Class 的不透明类型。类不能使用前面为实例显示的声明语法定义属性,但它们可以接收消息。
我假设这myClass
是(字面上)一个类的名称(尽管通常类以大写字母开头;我假设这是一个不遵循命名约定的类)。
Objective-C 中的消息发送语法有两种情况。您提到的一个是左侧是否是一个表达式,其计算结果为指向对象的指针;消息被发送到该对象。第二,如果左边是一个标识符,它是一个类的名称,那么编译器会将消息发送到该类的类对象。从技术上讲,编译器会将指向类对象的指针作为第一个参数传递给objc_msgSend()
. 这是可能的,因为编译器为每个类安排了类对象的结构和位置,因此它知道该类对象的地址。
直观地,您可以认为[myClass doSomething];
类似于
Class foo = objc_getClass("myClass");
[foo doSomething];
或者
Class foo = NSClassFromString(@"myClass");
[foo doSomething];
除了它不需要执行运行时查找来获取指向类对象的指针——编译器在编译时就知道指针。
Mike Ash 对工作原理有很好的解释objc_msgSend
:Friday Q&A 2012-11-16: Let's Build objc_msgSend。
运行时将消息转换为 SEL,然后检查该类是否使用该 SEL 响应消息,包括超类继承的方法。如果它响应,它将执行该方法。