iOS 底层探索篇 —— 类的原理分析-下
成员变量 & 属性 & 实例变量
-
属性(property)
:在OC中是通过@property开头定义,且是带下划线成员变量 + setter + getter方法的变量 -
成员变量(ivar)
:在OC的类中{}中定义的,为基本数据类型,且没有下划线的变量 -
实例变量
:通过当前对象类型,具备实例化的变量,是一种特殊的成员变量
,例如 NSObject、UILabel、UIButton或者自己创建的类等
那么在我们的类中,哪些是成员变量,哪些是属性,哪些是实例变量呢根据上文的解释我们知道: -
属性
:nickName,acnickName,nnickName,anickName,name,aname。 -
成员变量
: hobby,a。 -
实例变量
: objc。
我们在clang
一下main文件, 探索一下底层结构来看一下属性和成员变量的关系
。
打开main.cpp文件,然后找到我们的LGPerson类。
我们看到,属性在cpp文件中,属性都没有用了。他会在cpp中被优化成带下划线
的成员变量并且自动
生成getter
和setter
。
我们注意到,为什么有的set方法
是用objc_setProperty
,有的确是通过内存平移赋值
,有得get方法是通过objc_getProperty
,有的确是通过内存平移取值呢。
我们想,所有的setter几乎都是同样的工作,就是赋值到一个内存区域,。如果我们每一个setter都要一个底层实现,那就太繁琐了,于是苹果就在底部封装来基类的方法。然后在中间创建了一个方法叫做objc_setProperty,底层针对objc_setProperty进行相应的底层代码实现,setter 通过中间方法objc_setProperty去调用基类方法。
接下来我们打开llvm
,然后搜索objc_setProperty
。
我们看到这里有个创建并返回objc_setProperty
方法的地方。
在看到这个方法的名字叫做getSetPropertyFn
,也就是这个方法是要去获得setproperty
方法的,我们在llvm 中搜索这个方法。
发现是个中间层代码,我们改为搜索GetPropertySetFunction
。
然后我们发现了这个函数的调用,并且发现当PropertyImplStrategy
为SetPropertyAndExpressionGet
和GetSetProperty
才会调用这个方法。
我们往上翻,看到了我们是去判断strategy
这个实例变量的种类,而strategy这个实例变量