关于 OC 底层的一个问题

2016-10-20 22:06:24 +08:00
 acumen

学习《 Objective-C 高级编程: iOS 与 OS X 多线程和内存管理》书中 98 页时,有几个疑问。

  1. 通过成员变量 isa 保持该类的结构体实例指针。这句话怎么理解?
  2. 关于图中 class_t 结构体怎么理解?(我的理解:是每个 OC 对象的实例所对应的结构体‘模版’?)

下图是书的内容

望大神指点。

2248 次点击
所在节点    C
13 条回复
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 结构体直接当成类就行。

这书是很久以前看过一部分,可能存在一些理解上的偏颇,仅供参考。
acumen
2016-10-21 00:39:09 +08:00
@coa 感谢你的解答,很详细。第一点想明白了。
第二点,我所了解的 objc_object 中的 isa 指向的是 objc_class 接下去 objc_class 其中的 isa 指向谁呢?
对于 oc 每个具体的类对应一个 meta-class , meta-class 其实也是基于 class_t ?这样说的话 class_t 就是所有对象的所对应的最底层的一个结构体了?

我的理解不知道有没有问题?
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 少了成员变量的定义,所以猜想除了这点外,底层内容应该确实是一样的。
mofet
2016-10-21 09:53:11 +08:00
http://www.jianshu.com/p/41735c66dccb
看看这个,通俗易懂。
Karsa
2016-10-21 12:04:47 +08:00
唉,电脑在恢复,本来想用手机简单聊一下的,然后发现越写越多,也是醉了,看来功夫还不到家,概括能力太弱。

isa 建立 class 跟 meta class 之间关系, meta class 继承关系。对象的 isa 指向类的地址,类的 isa 指向自己的 meta class , meta class 的 isa 指向父类的地址,顶层 meta class 的 isa 指向自己。

嗯,我记得应该是这样 ~
Karsa
2016-10-21 12:06:17 +08:00
@Karsa 这些对象应该都是题主说的那个数据结构的实例,大概就是这样吧
acumen
2016-10-21 12:14:37 +08:00
@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 )。

卒.
acumen
2016-10-21 12:17:29 +08:00
@mofet 这篇博文, isa 指针是很清晰,我想弄明白的是,对象和类背后结构体之间的关系 并且和图中的对应关系。谢谢回复
acumen
2016-10-21 12:20:46 +08:00
@Karsa 你所说的 “ meta class 的 isa 指向父类的地址” ,应该是 meta class 的 isa 直接指向的是顶层的 meta class 吧
acumen
2016-10-21 12:23:17 +08:00
@Karsa 我认为也是这样,所有的对象都是 class_t 的实例。 但是这样的话。 class_t , objc_object , objc_class 这三者的关系又是如何呢。
acumen
2016-10-21 17:45:11 +08:00
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 为标准。

如果有更好的理解,欢迎分享啊~
coa
2016-10-21 19:15:28 +08:00
其他关系都挺清晰了~自己也是没看明白这一页 objc_class 和 class_t 的关系,感觉 objc_object 后边接着 class_t 就挺顺畅的,不明白 objc_class 的作用~~不是纯 C 出身看这些源码看得好纠结~~ =。=
acumen
2016-10-21 19:46:29 +08:00
@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 结构体的实例。

这样的思路好像也很清晰。就是不知道自己理解的有没有问题。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/314261

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX