clean memory & dirty memory
在WWDC中有介绍到clean memory和dirty memory的概念,在类的结构中对应class_ro_t和class_rw_t,上一篇中我们探索了属性在bit中的位置,在properties中都能找到,但没有找到属性address的位置。
在class_rw_t中p $3->ro()
按照同样的方法获取其中的ivars
p $6.ivars
打印其中的内容,可以看到当前定义的address属性
成员变量和属性的区别
通过clang查看生成的cpp文件,name属性被编译成_name的成员变量,属性被注释
不同的是属性同时生成getter和setter方法
所以属性就是ivar + getter + setter
setProperty & 内存平移
在编译cpp中发现同样是属性,name调用的是setProperty方法而nickName的setter方法是内存平移的方式
这是在LLVM中做了优化,对用copy修饰的属性进行了objc_setProperty和objc_getProperty的方法调用,其中涉及到深拷贝和浅拷贝的问题。
类方法和元类
除了当前探索中的成员变量之外,还有一个当前没有找到的方法--类方法
对象方法和类方法可以重名,而对于底层而言并不区分对象方法和类方法,都是函数。那么如果都存储在类中,同名函数就无法区分是对象方法还是类方法,于是苹果通过元类来进行类方法的存储。
通过x/4gx拿到isa拿到元类
接着进行同分析类一样的操作
于是我们在元类中找到了类方法
除了用lldb查看相关的内容,可以通过runtime的方法直接获取相关内容。
Method class_getClassMethod(Class cls, SEL sel)
{
if (!cls || !sel) return nil;
return class_getInstanceMethod(cls->getMeta(), sel);
}
从源码中可以看到获取类方法也是调用的class_getInstanceMethod, 说明不区分对象方法和类方法。