理解Objective-C运行时

理解Objective-C运行时,objective-c,objective-c-runtime,Objective C,Objective C Runtime,这是《Objective-C运行时编程指南》的摘录: 创建新对象时,将为其分配内存,并初始化其实例变量。对象变量中的第一个变量是指向其类结构的指针。这个名为isa的指针使对象能够访问其类,并通过该类访问它从中继承的所有类 isa在NSObject中声明如下: Class isa; 而类只不过是指向结构的指针 typedef struct objc_class *Class; 现在让我们看看这个结构: struct objc_class { Class isa; #if !__OBJC2

这是《Objective-C运行时编程指南》的摘录:

创建新对象时,将为其分配内存,并初始化其实例变量。对象变量中的第一个变量是指向其类结构的指针。这个名为isa的指针使对象能够访问其类,并通过该类访问它从中继承的所有类

isa在
NSObject
中声明如下:

Class   isa;
只不过是指向结构的指针

typedef struct objc_class *Class;
现在让我们看看这个结构:

struct objc_class {
Class isa;

#if !__OBJC2__
Class super_class                                        OBJC2_UNAVAILABLE;
const char *name                                         OBJC2_UNAVAILABLE;
long version                                             OBJC2_UNAVAILABLE;
long info                                                OBJC2_UNAVAILABLE;
long instance_size                                       OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif

}
我们可以看到,在最新版本的Objective-C中,指向超类(以及除另一个isa之外的结构的所有其他成员)的指针是不可用的


所以我的问题是,如果
super\u class
指针不可用,对象如何访问其超类?它是否通过另一个isa指针访问超类?但它究竟是如何发生的呢?它是如何工作的?有人能解释一下吗

不要依赖类结构的任何内部结构。--您也不依赖其他pals实例变量!你在找房子

您可以在
runtime.h


要获取超类,例如call
class\u getSuperclass

只需检查源文件

所以
Class
实际上是指向
Class\u t

这是一个容纳一切的结构


无论如何,这些都是内部实施细节,不应依赖。因此,不要编写依赖于这些的代码,因为它们可能在下次运行时更新时被破坏

您在哪里找到该定义的?这个头文件显示了一个不同的头文件:我在objc/runtime.hit中找到了它,它取决于运行时版本,我想你是对的;我看到的是一个旧版本。@特洛伊木马这个版本是新的嘿,但为什么当我单击类上的“跳转到定义”时,我会在这里看到typedef struct objc_Class*Class@AndreyChernukha我想这是为了让编译器看到隐藏了实际实现细节的东西。关于objc4项目,我注意到一件有趣的事情是Visual Studio项目文件以及Xcode项目文件。这些是实现细节,因此您无法看到它们。因为
Class
是一种指针类型,所以只要代码使用指针,它就可以指向任何东西。我是否理解没有办法通过Xcode找到类定义?
Class class_getSuperclass(Class cls)
{
    return _class_getSuperclass(cls);
}
#define newcls(cls) ((class_t *)cls)

Class 
_class_getSuperclass(Class cls)
{
    return (Class)getSuperclass(newcls(cls));
}

static class_t *
getSuperclass(class_t *cls)
{
    if (!cls) return NULL;
    return cls->superclass;
}
typedef struct class_t {
    struct class_t *isa;
    struct class_t *superclass;
    Cache cache;
    IMP *vtable;
    uintptr_t data_NEVER_USE;  // class_rw_t * plus custom rr/alloc flags

    class_rw_t *data() const { 
        return (class_rw_t *)(data_NEVER_USE & ~(uintptr_t)3); 
    }
    void setData(class_rw_t *newData) {
        uintptr_t flags = (uintptr_t)data_NEVER_USE & (uintptr_t)3;
        data_NEVER_USE = (uintptr_t)newData | flags;
    }

    bool hasCustomRR() const {
#if CLASS_FAST_FLAGS_VIA_RW_DATA
        return data_NEVER_USE & (uintptr_t)1;
#else
        return data()->flags & RW_HAS_CUSTOM_RR;
#endif
    }
    void setHasCustomRR(bool inherited = false);

    bool hasCustomAWZ() const {
#if CLASS_FAST_FLAGS_VIA_RW_DATA
        return data_NEVER_USE & (uintptr_t)2;
#else
        return data()->flags & RW_HAS_CUSTOM_AWZ;
#endif
    }
    void setHasCustomAWZ(bool inherited = false);

    bool isRootClass() const {
        return superclass == NULL;
    }
    bool isRootMetaclass() const {
        return isa == this;
    }
} class_t;