接着上文iOS类与方法底层探析(一)-源码探析我们来了解下类在运行过程中的内存存储结构,以及iOS类与方法底层探析(三)-方法调用的消息机制;
开源代码objc4-750
最新源码bjc-756-2点开command+f
搜索objc
截屏2019-12-14下午6.21.51.png
配置错误请参考编译RunTime源码错误处理
根据开源代码,可以将运行时类的结构用图来表示,如图p107所示。运行时类的结构中多了一个class_ rw_ t,它表示该结构可读、可写( Read、Write), 所以在运行时添加的一些动态方法都是添加到该结构上的。p107.jpg
为了更加清晰地展示内存中的结构存储,编写了一个简单的Demo程序,用来显示内存中的结构变量(Demo)。打开项目,找到源文件NSObject+Class.m
,从该文件里面将开源代码中的结构定义拿出来。在printIntermalClass方法中将class转换成对应的结构并获取其中的readwrite结构,在该处下断点,运行程序,便可以在调试窗口看到结构中对应的信息了,如图所示。
根据打印的class
和meta-class
对象分别打印它的属性以及方法,0x108f3e730
类的实例,第二个打印的0x108f3e708
class是PlatoJobs
的meta-class
保存的类方法。
2019-12-14 18:51:55.774388+0800 ClassAny[3550:148687] Class:PlatoJobs Address:0x108f3e730
2019-12-14 18:51:55.774614+0800 ClassAny[3550:148687] Class:PlatoJobs Address:0x108f3e708
2019-12-14 18:51:55.786849+0800 ClassAny[3550:148687] Class:NSObject Address:0x7fff89cc4558
(lldb) po [0x108f3e730 PrintVariables]
<__NSArrayM 0x60000158c2d0>(
offset: 8 name:_myProperty type:@"NSString"
)
(lldb) po [0x108f3e708 PrintMethods]
<__NSArrayM 0x60000158c0f0>(
name:PJ_ClassMethod type encode:v16@0:8 IMP:0x108f39520
)
(lldb) po [0x108f3e708 PrintVariables]
<__NSArrayM 0x60000158c2a0>(
)
(lldb) po [0x108f3e730 PrintMethods]
<__NSArrayM 0x60000158c180>(
name:pjmethod type encode:v16@0:8 IMP:0x108f394f0,
name:myProperty type encode:@16@0:8 IMP:0x108f39550,
name:setMyProperty: type encode:v24@0:8@16 IMP:0x108f39580,
name:.cxx_destruct type encode:v16@0:8 IMP:0x108f395c0
)
(lldb)