objc_msgSend()发送表
我需要清除一些混乱,理解objc_msgSend()。 请慷慨地给予详细的答案。 🙂
这是我从Apple Doc了解的。
当一个消息被发送到一个对象时,消息传递函数跟随该对象的isa指针,指向在调度表中查找方法select器的类结构。 如果在那里找不到select器,objc_msgSend()会跟随指向超类的指针(这里是混淆),并尝试爬上类层次结构。
在这里,超类是否获得分配的内存,并且是一个可用于该超类的指针? 上面的报价是这样说的吗?
如果你看看NSObject的ObjC-2.0声明,你会看到:
@interface NSObject <NSObject> { Class isa; }
哪里类是:
typedef struct objc_class *Class;
而objc_class是:
struct objc_class { struct objc_class *isa; struct objc_class *super_class; const char *name; long version; long info; long instance_size; struct objc_ivar_list *ivars; struct objc_method_list **methodLists; struct objc_cache *cache; struct objc_protocol_list *protocols; };
因此,这isa
指针 – NSObject
的第一个字段,也是每个子类中的第一个字段 – 是指向该objc_class
结构的指针。 结构的其余部分描述了这个类的细节。 该super_class
字段指向描述超类的objc_class
结构。
当objc_msgSend()
试图分派一个方法到一个NSMutableString
,它首先查看描述一个NSMutableString
实例的objc_class
的方法列表。 如果没有find方法,它会查看super_class
结构并在那里search。 如果它找不到,它会在super_class
的super_class
。
也就是说,任何给定类的isa
所指向的结构中的super_class
指针都是NSObject
(通常)的类层次结构的链表。 如果super_class
字段是空的,那将是一个根类。
内存分配或多或less地以类似的方式完成。 instance_size
字段指定实例的大小,从而指定要分配的内存量。
或多或less。 所有这些结构现在都是不透明的。 正如理查德·罗斯三世在评论中所说的, 你必须使用内省function来获得这些结构的内容 。 这允许苹果改变实现细节而不需要重新编译所有的东西。