【靠谱程序员】【6】属性、成员变量与存取方法
本文最后更新于:2021年12月22日 上午
【靠谱程序员】系列目录
问:
@property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的?
答:
1、@property 的本质
1 |
|
翻译出来就是:
属性(property)= 实例变量(ivar)+ 存取方法(getter和setter)
实例变量用于存储数据
存取方法用来读取写入该实例变量的数据
(有swift开发经验的人对这个感触应该表较深(存储属性和计算属性))
编译器会自动为@property添加实例变量和存取方法,当你重写存取方法中的一个的时候不用手动写实例变量:@synthesize name = _name;
,但是当你同时重写setter和getter方法时,你需要添加这行代码才能通过编译。
2、ivar、getter、setter 是如何生成并添加到这个类中的?
“自动合成”( autosynthesis)
完成属性定义后,编译器会自动编写访问这些属性所需的方法,此过程叫做“自动合成”(autosynthesis)。需要强调的是,这个过程由编译 器在编译期执行,所以编辑器里看不到这些“合成方法”(synthesized method)的源代码。除了生成方法代码 getter、setter 之外,编译器还要自动向类中添加适当类型的实例变量,并且在属性名前面加下划线,以此作为实例变量的名字。在前例中,会生成两个实例变量,其名称分别为 _firstName 与 _lastName。也可以在类的实现代码里通过 @synthesize 语法来指定实例变量的名字。
1 |
|
反编译相关的代码,他大致生成了五个东西
1 |
|
也就是说我们每次在增加一个属性,系统都会在 ivar_list 中添加一个成员变量的描述,在 method_list 中增加 setter 与 getter 方法的描述,在属性列表中增加一个属性的描述,然后计算该属性在对象中的偏移量,然后给出 setter 与 getter 方法对应的实现,在 setter 方法中从偏移量的位置开始赋值,在 getter 方法中从偏移量开始取值,为了能够读取正确字节数,系统对象偏移量的指针类型进行了类型强转。
拓展
property在runtime中是objc_property_t定义如下:
1 |
|
而objc_property是一个结构体,包括name和attributes,定义如下:
1 |
|
而attributes本质是objc_property_attribute_t,定义了property的一些属性,定义如下:
1 |
|
而attributes的具体内容是什么呢?其实,包括:类型,原子性,内存语义和对应的实例变量。
例如:我们定义一个string的property@property (nonatomic, copy) NSString *string;
,通过 property_getAttributes(property)
获取到attributes并打印出来之后的结果为T@”NSString”,C,N,V_string
其中T就代表类型,可参阅Type Encodings,C就代表Copy,N代表nonatomic,V就代表对于的实例变量。
Code | Meaning |
---|---|
c | A char |
i | An int |
s | A short |
l | A long l is treated as a 32-bit quantity on 64-bit programs. |
q | A long long |
C | An unsigned char |
I | An unsigned int |
S | An unsigned short |
L | An unsigned long |
Q | An unsigned long long |
f | A float |
d | A double |
B | A C++ bool or a C99 _Bool |
v | A void |
* | A character string (char *) |
@ | An object (whether statically typed or typed id) |
# | A class object (Class) |
: | A method selector (SEL) |
[array type] | An array |
{name=type…} | A structure |
(name=type…) | A union |
bnum | A bit field of num bits |
^type | A pointer to type |
? | An unknown type (among other things, this code is used for function pointers) |
联系方式
邮箱: xiebangyao_1994@163.com
相关账号:
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!