头脑风暴Objective-C运行时

时间:2014-04-23 17:41:35

标签: ios objective-c c objective-c-runtime

每次我回到了解Objective-C运行时,我最终都弄乱了我的大脑。据我所知(通过阅读一些令人敬畏的文章,如MetaclassesObj-C Runtime),Objective-C类实际上是类对象,例如NSString本身就是其根元类的对象。此外,它所谓的ivar“ isa ”指针保留了所有基本细节,如超类,方法列表,名称等。以下是仅基于此理论的一些问题 -

(1)。检查objc / runtime.h的当前声明,你会发现以下结构声明:

    struct objc_class {
        Class isa  OBJC_ISA_AVAILABILITY;

>     #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**

    } OBJC2_UNAVAILABLE;

我希望这意味着从Objective-C 2.0开始,这个结构中的所有内容都是“ isa ”指针。这似乎淡化了运行时理论的所有逻辑。这些细节如超类,方法列表等现在存储在哪里?


(2)。技术上 isa 是指向struct objc_class 的指针,它本身有 isa 作为其成员。所以当我尝试访问时(在AppDelegate中说):

     NSLog(@"class isa ptr %@", isa->isa);

NSLog(@"class isa %@", ((Class)[NSString class])->name);

我收到编译时错误:

  • 成员引用基类型'Class'不是结构或联合。

为什么呢?我认为它是访问结构成员的正确语法


(3)。使用NSLog在控制台上打印“类”(我指的是typedef struct objc_class *Class)对象显示了Objective-C类的名称。

NSLog(@"NSObject class %@", [NSObject class]);

怎么回事? class是一个返回'Class'对象的类方法。如果要打印类名,则应按如下方式打印:

NSLog(@"NSObject class %@", ((Class)[NSObject class])->name);

帮我弄清楚我错过了什么。

1 个答案:

答案 0 :(得分:2)

(1)这些细节如超类,方法列表等现在存储在哪里?

在ObjC 2.0中,所有类的详细信息都是私有实现细节。也许数据布局实际上是相同的,也许不是。

(2)为什么我无法访问字段name

你引用的头文件说在ObjC 2.0中只有isa指针在那里,所有其他的东西都消失了。

(3)为什么NSLog[NSString class]打印为NSString

因为NSLog-[NSString stringWithFormat:]一样,会在提供的对象上调用description方法。显然,方法+[Class description]返回类的名称。