第6条:理解属性”这一概念

1. 属性概念

属性”(property)是Objective-C的一项特性用于封装对象中的数据
Objective-C对象通常会把所需要的数据保存各种实例变量实例变量一般通过存取方法”(access method)来访问。Objective-C 2.0后,经“属性”这一特性引入开发者可以编译器自动编写与属性相关的存取方法

2. 实例变量

*** 2.1 在类接口public区段中声明实例变量的劣势? ***
这种做法在编译期已经将实例变量代码替换为特定的“偏移量”(offset)了,所以,如果又增加了一个新的实例变量,就会出现问题
图例

*** 2.2 Objective-C的解决办法! ***
*** 2.2.1 应用程序二进制接口 ***
Objective-C引入了“应用程序二进制接口”(Application Binary Interface,ABI)。
这种做法是,把实例变量当作一种存储偏移量所用的“特殊变量”,交由“对象”保管。偏移量会在运行查找,如果类的定义变了,那么存储偏移量也就变了,这样的话,无论何时访问实例变量,总能使用正确偏移量,甚至可以运行期向类中新增实例变量。

总结可以在“classcontinuation分类”或实现文件定义实例变量。所以,不一定要在接口把全部实例变量都声明好,可以将某些变量从接口public区段里移走,以便保护与类实现有关的内部信息

*** 2.2.2 另外一种解决办法 ***
尽量不要直接访问实例变量,而应该通过存取方法来做。但是,存取方法有着严格命名规范,所以,Objective-C引入了属性@property语法,让编译器自动编写存取方法。当然,开发者也可以自己编写存取方法

3. 属性@property

属性property),能够访问封装对象里的数据开发可以把属性当做一种简称,其意思是说:编译器自动编写一套存取方法,用以访问给定类型具有给定名称的实例变量

@property NSString *firstName;

 

*** 3.1 属性的优势? ***

*** 3.2 @synthesis语法 ***
通过@synthesis语法可以直接指定实例变量的名字,但一般情况下无须修改默认的实例变量名

@synthesis firstName = _myFirstName;

*** 3.3 @dynamic语法 ***
使用@dynamic关键字,它会告诉编译器不要自动创建实现属性所用的实例变量,也不要为其创建存取方法。而且,在编译访问属性的代码时,即时编译器发现没有定义存取方法,也不会报错,它相信这些方法能在运行找到

@dynamic firstName, lastName;

 

*** 3.4 属性特质 ***
属性可以拥有的特质有四类:
*** 3.4.1 原子性 ***
在默认情况下,由编译器合成的方法会通过锁定机制确保其原子性(atomicity)。如果属性具备nonatomic特质,则不使用同步锁。开发iOS程序,属性都声明nonatomic,这样做的原因是:在iOS中使用同步锁的开销较大,会带性能问题,而且atomic并不能保证“线程安全

*** 3.4.2 读/写权限 ***

*** 3.4.3 内存管理语义 ***
这一特质仅会影响设置方法”。

*** 3.4.4 方法名 ***

*** 3.4.5 属性特质的总结 ***
通过上述特质,可以微调编译器所合成的存取方法。不过需要注意:若是自己来实现这些存取方法,那么应该保证其具备相关属性所声明的特质。
例如,如果将某个属性声明copy,那么就应该在“设置方法”中拷贝相关对象,否则会误导该属性的使用者,而且,若是不遵从这一约定,还会令程序产生bug

/* 头文件  */
@property (copy) NSString *firstName;
@property (copy) NSString *lastName;

- (id)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName;

/* 实现文件  */

- (id)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName{
    if (self = [super init]){
        // firstName有可能是NSMutableString*,该字符串的值可能会在对象不知情的情况下遭人修改。所以,要拷贝一份“不可变”的字符串,确保对象中的字符串值不会无意间变动。
        _firstName = [firstName copy]; 
        _lastName = [lastName copy];
    }
    return self;
}

尽量使用不可变的对象,也就是说,属性应该设为“只读”。用初始化方法设置好属性值之后,就不能再改变了。

@property (copy, readonly) NSString *firstName;
@property (copy, readonly) NSString *lastName;

 

要点

原文地址:https://blog.csdn.net/qq_24252589/article/details/129936749

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_44656.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注