【问题标题】:objc_msgSend() dispatch tableobjc_msgSend() 调度表
【发布时间】:2014-04-28 22:29:22
【问题描述】:

我需要清除一些杂乱的想法才能理解 objc_msgSend()。 请慷慨地提供详细的答案。 :)

这是我对 Apple Doc 的理解。

当向对象发送消息时,消息传递函数如下 对象的 isa 指针,指向它在其中查找的类结构 调度表中的方法选择器。如果找不到选择器 在那里,objc_msgSend() 跟随指向超类的指针(这里是 混乱)并试图爬上类层次结构。

在这里,超类是否获得了内存分配和该超类可用的 isa 指针?上面的引文是这样说的吗?

【问题讨论】:

  • 它没有说明分配,每个对象都有一个 isa 指针,所以不清楚你在这里说的是哪个 isa。你能澄清一下你的意思吗?
  • 你可以阅读source code
  • @Chuck 这需要一些澄清恕我直言,每个对象都有一个类(这是一个简单的结构),每个类都有一个 isa 指针。
  • @Chuck 并非每个对象都有一个 isa“指针”。标记的对象,而在 ARM64 上,isa 变量 不是指针,它根本不存在。您应该始终使用object_getClass 来获取对象的类,并且永远不要依赖 isa 指针。
  • @Chandu:这与您引用的段落没有任何关系。我想也许你把一个类的 isa 和它的实例的 isas 混淆了。每个类都有一个 isa,所以每个类都有一个 isa,但实例本身只有一个。

标签: ios objective-c


【解决方案1】:

如果您查看 NSObject 的 pre-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 的方法列表。如果没有找到该方法,它会查看super_class 结构并在那里搜索。如果在那里找不到它,则在super_classsuper_class 中查找。

即任何给定类的isa 指向的结构中的super_class 指针是类层次结构中一直到NSObject 的链表(通常)。如果super_class 字段为空,那将是一个根类。

内存分配或多或少是以类似的方式完成的。实例的instance_size 字段指定实例的大小,从而指定要分配的内存量。

或多或少。所有这些结构现在都是不透明的。正如 Richard Ross III 在 cmets 中所说,您必须使用自省函数来获取这些结构的内容。这允许 Apple 更改实现细节,而无需重新编译所有内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多