每次我回到了解Objective-C运行时,我最终都弄乱了我的大脑。据我所知(通过阅读一些令人敬畏的文章,如Metaclasses,Obj-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);
我收到编译时错误:
为什么呢?我认为它是访问结构成员的正确语法
(3)。使用NSLog在控制台上打印“类”(我指的是typedef struct objc_class *Class
)对象显示了Objective-C类的名称。
NSLog(@"NSObject class %@", [NSObject class]);
怎么回事? class是一个返回'Class'对象的类方法。如果要打印类名,则应按如下方式打印:
NSLog(@"NSObject class %@", ((Class)[NSObject class])->name);
帮我弄清楚我错过了什么。
答案 0 :(得分:2)
在ObjC 2.0中,所有类的详细信息都是私有实现细节。也许数据布局实际上是相同的,也许不是。
name
?你引用的头文件说在ObjC 2.0中只有isa
指针在那里,所有其他的东西都消失了。
NSLog
将[NSString class]
打印为NSString
?因为NSLog
与-[NSString stringWithFormat:]
一样,会在提供的对象上调用description
方法。显然,方法+[Class description]
返回类的名称。