Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法 对象属性 property

1. Java 或 C++ 中,使用publish,private等关键字来声明变量的作用域。
这种写法的问题是:对象布局在编译器(compile time)就已经固定了。碰到访问其中变量的代码,编译器就把它替换为“偏移量”(offset)。这个偏移量是硬编码(hardcode),表示该变量距离存放对象的内存区域的起始地址有多远。
这样子在修改了类定义后必须重新编译。否则offset是错误的。
例如某个代码库的代码使用了一份旧的类定义,如果和其相链接的代码使用了新的定义,那么运行时就会出现不兼容现象。
OC的做法,就是把实例变量当作一种存储偏移量所用的“特殊变量”,交由“类对象”保管。偏移量会在运行期查找,如果类的定义改变了,那么存储的偏移量也就变了。这样的话,无论何时访问实例变量,总能使用正确的偏移量。
甚至还可以在运行期间向类中新添实例变量。
这就是稳固的“应用程序二进制接口”(Application Binary Interface,ABI)。

2. 如果不想令编译器自动合成存取方法,则可以自己实现。如果只实现了其中一个存储方法,则另一个还是会由编译器来合成。

3. 使用 @dynamic 关键字可以阻止编译器自动合成。而且在编译访问属性的代码时,及时编译器发现定义的存取方法,也不会报错。
它相信这些在运行期能找到。

4. 原子性
默认情况下,由编译器所合成的方法会通过锁定机制确保其原子性(atomicity);

5. 读/写权限
① 具备 readwrite 特质的属性拥有“获取方法”和“设置方法”。@synthesize 会自动生成这两个方法。
② readonly 特质仅拥有获取方法。

6. 内存管理语义
属性用于封装数据,而数据则要有“具体的所有权语义”(concrete ownership semantic);
① assign:设置器置灰执行针对“纯量类型”的简单赋值操作。
② strong:设置新值时,会先保留新值,并释放旧值,然后再将新值设置上去。
③ weak:设置新值时,既不保留新值,也不释放旧值。当属性所指的对象遭到摧毁时,属性值也会清空。
④ unsafe_unretained:语义和assign想同,但适用于对象。该特质表达一种“非拥有”,当目标对象被摧毁,属性值不会自动清空,这点和weak不同。
⑤ copy:设置新值时不保留新值,将其“拷贝”。只要属性所用的对象是“可变的”(mutable),就应该在设置新属性值时拷贝一份。

7. 方法名
① getter = <name> 指定“获取器”的方法名。如果某属性时Boolean型,而想在其获取器上加“is”前缀。则可指定。
例如说有个属性这样定义:
@property (nonatomic, getter = isOn) BOOL on;

② setter = <name> 指定“设置方法”;

注:若是自己来实现这些存储方法,那么应该保证其具备相关属性所声明的特质。
例如声明特质为copy,则要在复制的时候使用copy。

决不应该在init方法(或者dealloc方法)中使用存取方法;

8. 在iOS中,使用同步锁的开销较大。一般情况下并不要求属性必须时原子的,因为这并不能保证“线程安全”,若要实现“线程安全”需采用更深层次的锁定机制才行。






Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法 对象属性 property,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。