我最近在这里读到,objective-c 对象作为结构存储在堆上。该结构包含对象 iVar、继承的 iVar 和 isa 指针。
我试图弄清楚当我向这个对象发送消息时,运行时如何找出要运行的代码?
我知道每个类都有一个类对象。这也存储在堆上吗?
我认为它的工作方式是运行时从结构中获取 isa 指针,使用它来调用类对象上的消息。它是否正确?
我最近在这里读到,objective-c 对象作为结构存储在堆上。该结构包含对象 iVar、继承的 iVar 和 isa 指针。
我试图弄清楚当我向这个对象发送消息时,运行时如何找出要运行的代码?
我知道每个类都有一个类对象。这也存储在堆上吗?
我认为它的工作方式是运行时从结构中获取 isa 指针,使用它来调用类对象上的消息。它是否正确?
简而言之,每个 Objective-C 实例都有一个指向其类的指针。该类包含一个元数据清单,其中包括该类实现的所有方法。当消息被发送到对象时——当调用方法时——运行时使用指向类的指针按名称查找方法并调用它(如果可以找到)。如果没有找到,运行时会在继承链上查找超类(它是每个类元数据的一部分)到 NSObject。如果最终找不到该方法,则运行时会进行一系列最后的努力,以查看它们是否是替代处理程序,并最终引发异常,如果不是。
如果你想了解更多细节,我写了一个关于 Objective-C 方法调度工作原理的多部分教程。 它有点过时了——不处理 ARC、标记指针或块作为 IMP——但仍然完全适用。
是的,类存储在堆中,但通常不在 malloc()d 内存中。类通常作为只读的共享内存加载。也就是说,对于系统上运行的所有应用程序NSString
,内存中只有一个类的副本。您可以动态创建类,这些类将在常规堆中,但它是非典型的。