// 系统版本:OS X 10.9.2 (13C64)
// Xcode版本:5.0.2 (5A3005)
对类的属性设置 getter和 setter,需要在相应类的声明部分中声明 getter 和 setter的声明,然后在相应的实现部分中实现 getter和 setter。XCode中提供了@property和 @synthesize关键字,可以省去我们不少写代码的时间。下面以
Person类来说明使用@property和@synthesize的一些细节。
假如Person类有一个_age(成员变量名以下划线开头)属性,手动实现 getter和 setter的声明和实现的方法是:
@interface Person : NSObject
{
int _age; // 默认是@protected 属性,子类也可以访问
}
- (int)age; // getter 声明
- (void)setAge:(int)age; // setter 声明
@end
@implementation Person
- (int)age // getter 实现
{
return _age;
}
- (void)setAge:(int)age // setter 实现
{
_age = age;
}
@end
如果使用@property关键字,一行代码就可以自动完成 getter和 setter 的声明和实现
@property int age;
这一行代码可以自动完成三件事
1. 自动声明一个私有成员变量 _age;(如果成员变量 _age已经存在,则不会再声明该成员变量,直接使用)
{
@private
int age;
}
2. 自动声明 age和 setAge:方法
- (int)age; // getter声明
- (void)setAge:(int)age; // setter声明
3. 自动实现 age和 setAge:
- (int)age // getter实现
{
return _age;
}
- (void)setAge:(int)age // setter实现
{
_age = age;
}
如果自定义的成员变量名是 age,而你只写了一句@propertyint age; Xcode会发出警告:Autosynthesized property'age' will use instance variable'_age', not existing instance variable'age'
也就是说XCode会自动完成 _age属性的 setter和 getter 的声明和实现
如果想让XCode自动完成 age属性的 setter和 getter 的实现,需要使用关键字 @synthesize 格式如下:
@synthesize age = age;
或者
@synthesize age
实现结果如下:
- (int)age // getter实现
{
return self.age;
}
- (void)setAge:(int)age // setter实现
{
self.age = age;
}
如果使用了@synthesize,而又自定义了 getter和 setter 中的一个,Xcode会发出警告:
Writable atomic property'属性' cannot pair a synthesized getter with a user defined setter
Writable atomic property'属性' cannot pair a synthesized setter with a user defined getter
总结:
@property用来设定 getter和 setter的名称,比如@property int age; setter就是 age, getter就是 setAge:
@synthesize指定 getter和 setter访问哪个属性:
如果没有写,默认访问的是加下划线的属性,也就是@synthesize age = _age,则 age和 setAge 访问的就是 _age
如果指定了属性,访问的就是指定的属性,比如@synthesize age = age;或者直接@synthesize age,则 age和 setAge访问的就是 _age
下面来一段测试:
#import <Foundation/Foundation.h>
@interface Person : NSObject
{ // 默认都是@protected属性,子类也可以访问
int _age;
int age;
int _height;
int height;
int _weight;
int weight;
int _money;
int money;
}
@property int age;
@property int height;
@property int weight;
@property int money;
- (void)test;
@end
@implementation Person
@synthesize height = _height; //访问的就是指定的 _height
@synthesize weight; //访问的就是指定的 weight,其实就是 @synthesize weight = weight;
// 其他没有指定的,默认访问的都是相应的带下划线的属性
- (void)setMoney:(int)money // 自定义了setter,不再自动生成,访问 money;自动生成 getter 访问 _money
{
self->money = money;
}
//分析结果: money 访问 _money; setMoney: 访问 money
- (int)height //自定义了 getter,不再自动生成,getter返回的永远是180;自动生成setter 访问 _height
{
return 180;
}
//分析结果:height不访问任何成员,只返回180; setHeight: 访问 _height
- (int)age //自定义 getter,不再自动生成,getter访问 age;自动生成 setAge: 访问的是 _age
{
return age;
}
//分析结果:age 访问 age; setAge: 访问 _age
//weight //getter 和 setter 都会自动生成,访问的是 weight
//分析结果:weight 访问 weight, setWeight: 访问 weight
- (void)test
{
// setAge: 访问的是 _age, = 10
// age = 默认值 0
//self.age 调用[self age] 访问的是age, 返回 0
NSLog(@"age=%d, _age=%d, self.age=%d", age, _age, self.age);
// setHeight: 访问的是 _height, = 160
// height = 默认值 0
//self.height 调用[self height],访问的是height,永远返回180
NSLog(@"height=%d, _height=%d, self.height=%d", height, _height, self.height);
// setWeight: 访问的是 weight ,= 50
// _weight = 默认值 0
//self.weight 调用[self weight], 访问的是weight, 返回 50
NSLog(@"weight=%d, _weight=%d, self.weight=%d", weight, _weight, self.weight);
// setMoney: 访问的是 money,= 2000
// _money = 默认值 0
//self.money 调用[self money] 访问的是 _money, 返回 0
NSLog(@"money=%d, _money=%d, self.money=%d", money, _money, self.money);
}
@end
int main()
{
Person *p = [Person new];
p.age = 10;
p.weight = 50;
p.height = 160;
p.money = 2000;
[p test];
return 0;
}