【靠谱程序员】【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 协议 ,转载请注明出处!