@property

2017-03-30  本文已影响0人  羚君

类的属性和实例变量是两个概念

类的属性声明通过关键字@property声明, 编译器在编译阶段将自动:1.为属性创建一个相对应的实例变量2.为属性创建getter,setter方法(getter,setter方法内部实际是存取背后的实例变量)。

注意,此时该类的实例对象。不仅有一个 私有的实例变量,而且还有一个 属性。可以对该属性直接进行getter,setter。说白了,该 属性 是相对应 私有实例变量 的外包装。用于封装内部的 实例变量。

声明为属性有诸多优点

声明为属性有很多好处,有许多配套的限定词,来令编译起自动帮你完成一些功能。

专为 属性 创造的 点运算符

通过'.'运算符,可以快速调用该属性的setter,getter方法。

限定词

(readwrite) || (readonly)

(getter = anotherName) 另命名属性的getter方法,取代原先的 setPropertyname 的方法

@synthesize

通过 @synthesize 可以显式指定属性背后的实例变量的名字:

1. @synthesize propertyA = _a ;  将背后的实例变量命名为_a

2.@synthesize propertyA ;  将背后的实例变量命名为与 属性 相同的名字

3.不实用@synthesize 声明。系统自动命名 实例变量 的名字为 _propertyA

自定义存取器方法

也可以根据需要手动定义 属性 的存取方法,例如

@property (readonly) NSString *fullName;

自动生成的话,就会生成一个仅仅返回 fullName 字符串的变量值。如果自定义的话:

- (NSString *)fullName {

return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];

}

就可以,在每次get fullName属性时,得到最新的fullName属性值。通过这种方式,属性 不一定需要有自己专属的 实例变量。

注意

编译器会自动声明实例变量与相对应的属性。但当你自定义了属性的getter和setter方法时,编译器会认为你已经掌控了属性的相关实现,就不会在为其自动创建相关联的实例变量。经测试,这个的确是个问题。如果实在需要的话,需要显式声明:

@synthesize property = _property;

经过测试,在不使用@synthesize语句的前提下。setter和getter方法若只声明其一,编译器还是会自动为@property声明的属性定义背后的实例变量。但只要是写了setter和getter方法,编译器就会报错。说没有找到该实例变量。

跟踪属性值的变化

类的成员属性,会被跟踪值的变化。如果不声明为属性,则实例变量无法被跟踪。

在初始化函数中不能通过getter,setter方法访问属性

在初始化函数中,永远要直接访问实例变量。因为存取函数可能会遭到子类的复写

存取方法的限定词

(readwrite) || (readonly):默认是readwrite

(atomic) || (nonatomic) : 默认为atomic,原子性保证属性是否可以同一事件被不同线程访问。

不通过声明属性的方式,创建类的实例变量

如果不想将 实例变量 声明为属性,则在@interface 或 @implementation 处,在大括号内声明实例变量。

在@interface的大括号中声明的变量,可以通过标记@public, @protect , @private 来表明他们的访问和继承规则。默认为@protect。

在@implementation大括号中声明的变量,一律为@private。即使使用了@public的限定词,也是失效的。

上一篇下一篇

猜你喜欢

热点阅读