首页 » iOS编程(第4版) » iOS编程(第4版)全文在线阅读

《iOS编程(第4版)》3.6 深入学习:属性合成

关灯直达底部

本章介绍过,属性会自动生成存取方法,也会自动声明和创建实例变量。实际上,我们还可以自定义生成过程,得到符合实际需要的实例变量和存取方法。

在头文件中声明属性时,只会生成存取方法的声明。为了让属性生成实例变量并实现存取方法,该属性必须被合成(synthesized)。通常情况下,编译器会自动合成属性并生成默认的实例变量和存取方法。如果需要自定义属性的合成方式,可以在实现文件中使用@synthesize指令:

@implementation Person

// 创建存取方法,方法名是age和setAge:,

// 同时创建实例变量_age

@synthesize age = _age;

// 其他方法

@end

以上代码与编译器自动合成的效果相同。赋值号左边的age表示需要创建存取方法,方法名是age和setAge:。右边的_age表示需要创建实例变量,变量名为_age。

也可以不写变量名,这样实例变量的变量名会和方法名相同:

@synthesize age;

// 和以下语句效果相同:

@synthesize age = age;

有时我们不希望属性自动生成实例变量和存取方法。例如,有一个Person类,类中有三个属性:spouse(配偶)、lastName(姓氏)和lastNameOfSpouse(配偶的姓氏)。

@interface Person : NSObject

@property (nonatomic, strong) Person *spouse;

@property (nonatomic, copy) NSString *lastName;

@property (nonatomic, copy) NSString *lastNameOfSpouse;

@end

在这个例子中,spouse和lastName属性需要生成实例变量,因为配偶和姓氏是个人基本信息。而lastNameOfSpouse属性则不用生成实例变量,因为可以通过spouse的lastName属性知道配偶的姓氏,所以不需要在两个Person对象中都生成实例变量,既浪费内存也容易出错。我们可以为lastNameOfSpouse属性自定义存取方法:

@implementation Person

- (void)setLastNameOfSpouse:(NSString *)lastNameOfSpouse

{

self.spouse.lastName = lastNameOfSpouse;

}

- (NSString *)lastNameOfSpouse

{

return self.spouse.lastName;

} 

@end

由于同时覆盖了存方法和取方法,编译器不会再为lastNameOfSpouse自动生成实例变量,和期望效果一致。