学习《 Objective-C 高级编程: iOS 与 OS X 多线程和内存管理》书中 98 页时,有几个疑问。
下图是书的内容
望大神指点。
1
coa 2016-10-21 00:03:51 +08:00
Objective C 基于 C 的基础上拓展出面对对象特性,所以该段实际上是把先假设你有 C 的基础来解释它的内部原理。试着返回去跳过 C 的内容直接来看:
1.“通过成员变量 isa 保持该类的结构体实例指针。”——直接用 OC 来描述就是:每一个初始化出来的实例,内部都有一个名为 isa 的指针指向它的类。类其实也是“对象”,把它称为“类对象”也未尝不可,在内存上表现和实例对象一毛一样。 2.“关于图中 class_t 结构体怎么理解?”——直接理解为实例的模板没错,或者说,抛开它 C 的解释,这就是类。这里 objc_class 和 class_t 可能会造成一些混淆,看起来 object_class 内部只是定义了 isa 指针, class_t 才是在这基础上增加定义了函数指针等其他东西,所以 class_t 才是和类相对应的。 当你向一个实例发送消息时,它会找到 isa 指向的地址,即类,类里存着所有消息名(选择器)和函数地址的对应列表,找到对应的函数并调用,就完成了一次消息发送。灵活地操作这过程就能实现 runtime 的各种黑魔法。 总而言之 OC 对象是在 C 的结构体上做了类型定义(当然内部实现肯定不止这么简单),你看到 objc_object 结构体直接当成实例对象,看到 class_t 结构体直接当成类就行。 这书是很久以前看过一部分,可能存在一些理解上的偏颇,仅供参考。 |
2
acumen OP @coa 感谢你的解答,很详细。第一点想明白了。
第二点,我所了解的 objc_object 中的 isa 指向的是 objc_class 接下去 objc_class 其中的 isa 指向谁呢? 对于 oc 每个具体的类对应一个 meta-class , meta-class 其实也是基于 class_t ?这样说的话 class_t 就是所有对象的所对应的最底层的一个结构体了? 我的理解不知道有没有问题? |
3
coa 2016-10-21 09:15:23 +08:00
objc_class 的 isa 指向 meta class 。 class 定义了实例方法的实现, meta class 定义了类方法的实现,这样实例方法和类方法都能通过 isa 实现消息发送。最末端的 isa 指向 NSObject ,而 NSObject 的 isa 指向自己。
meta class 是为了让类方法也能通过 isa 进行消息传递,除了比 class 少了成员变量的定义,所以猜想除了这点外,底层内容应该确实是一样的。 |
4
mofet 2016-10-21 09:53:11 +08:00
http://www.jianshu.com/p/41735c66dccb
看看这个,通俗易懂。 |
5
Karsa 2016-10-21 12:04:47 +08:00 via iPhone
唉,电脑在恢复,本来想用手机简单聊一下的,然后发现越写越多,也是醉了,看来功夫还不到家,概括能力太弱。
isa 建立 class 跟 meta class 之间关系, meta class 继承关系。对象的 isa 指向类的地址,类的 isa 指向自己的 meta class , meta class 的 isa 指向父类的地址,顶层 meta class 的 isa 指向自己。 嗯,我记得应该是这样 ~ |
7
acumen OP @coa 我来总结一下,大神看看对不对。
现在我们涉及到 objc_object , objc_class , isa , meta-class , class_t , NSObject 这几个。 objc_object 其实就是我们常见的 id 在 C 语言中的表示, objc_object 结构体中的 isa 指向 objc_class , objc_class 中的 isa 指向 meta-class 。 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; 这个是 objc.h 中 objc_class 的定义。这样说 meta-class 也是一个 objc_class 。 class_t 这里就这样理解:其实每个对象和类,在 runtime 中都对应一个结构体,而生成这样的结构体需要一个‘模版’(这里解释了文中‘基于’的意思)。 结合网上流传的这张图。这里的 instance of subclass 对应 objc_object , class 对应 objc_class , meta class 对应的还是 objc_class 。 ![]( ) 至于 NSObject 所对应的 meta class 就是上图右上角的 root class ( meta )。 卒. |
8
acumen OP @mofet 这篇博文, isa 指针是很清晰,我想弄明白的是,对象和类背后结构体之间的关系 并且和图中的对应关系。谢谢回复
|
9
acumen OP @Karsa 你所说的 “ meta class 的 isa 指向父类的地址” ,应该是 meta class 的 isa 直接指向的是顶层的 meta class 吧
|
10
acumen OP @Karsa 我认为也是这样,所有的对象都是 class_t 的实例。 但是这样的话。 class_t , objc_object , objc_class 这三者的关系又是如何呢。
|
11
acumen OP http://blog.ibireme.com/2013/11/25/objc-object/
http://stackoverflow.com/questions/15309497/understanding-objective-c-runtime/15309657#15309657 由上面两个资料,大体上可以明白,或者说是猜想其中的机制。 class_t 是 Class 的实际结构。和上面说的一样。在 runtime 中生成一个对应的结构体,其中的成员都是以 class_t 为标准。 如果有更好的理解,欢迎分享啊~ |
12
coa 2016-10-21 19:15:28 +08:00
其他关系都挺清晰了~自己也是没看明白这一页 objc_class 和 class_t 的关系,感觉 objc_object 后边接着 class_t 就挺顺畅的,不明白 objc_class 的作用~~不是纯 C 出身看这些源码看得好纠结~~ =。=
|
13
acumen OP @coa 是啊,就是这一点不弄明白,感觉缺点什么。现在姑且 class_t 作为底层的结构体( stackoverflow 上那个歪果仁的意思好像是说 在最底层的 Class 和 class_t 指针之间可以强转,就说明结构体内的结构是一致的吧)。然后 “ instance of subclass 对应 objc_object , class 对应 objc_class , meta class 对应的还是 objc_class ” 按图来。在 runtime 中,像 objc_object 和 objc_class 的结构体都是动态按 class_t 生成的,所以也可以把所有对象的实例都是 class_t 结构体的实例。
这样的思路好像也很清晰。就是不知道自己理解的有没有问题。 |