文章来源: http://blog.sina.com.cn/s/blog_6b1e4a0601019oge.html
setter getter 方法统称为存取方法,ObjectiveC中,在对其他对象的属性进行操作时,应该始终使用对象所提供的存取方法,永远不要直接改变其他对象属性的值。
举个汽车的例子:
在没有setter getter 方法时,我们会这样来构造一辆汽车:(最简单的汽车包括一个发动机和4个轮胎)
class Engine.h
@interface Engine :NSObject
@end
class Engine.m
@implementation Engine
-(NSString *) description{
return @"I am an engine. Vroom!";
}
@end
class Tires.h
@interface Tires :NSObject
@end
class Tires.m
@implementation Tires
-(NSString *) description{
return @"I am a tire. I last a while."'
}
@end
class Car.h
@interface Car : NSObject
{
Engine *engine;
Tires *tires[4];
}
-(void)print;
@end
class Car.m
@implementation Car
-(id) init{
if(self = [super init]){
engine = [Engine new];
tires[0] = [Tires new];
tires[1] = [Tires new];
tires[2] = [Tires new];
tires[3] = [Tires new];
}
return self;
}
-(void) print{
NSLog(@"%@",engine);
NSLog(@"%@",tires[0]);
NSLog(@"%@",tires[1]);
NSLog(@"%@",tires[2]);
NSLog(@"%@",tires[3]);
}
@end
main.m
int main(int argc, const char *argv[])
{
Car *car;
car = [Car new];
[car print];
return 0;
}
在用setter 和 getter 方法后,Engine 和 Tires 类中代码不变,主要变化代码如下:
class Car.h
@interface Car : NSObject
{
Engine *engine;
Tires *tires[4];
}
-(void) setEngine:(Engine *)newEngine;
-(Engine *) engine;
//getter方法不能用get作为方法的前缀,get 在cocoa中有着特殊的含义;
-(void) setTire:(Tires *)tire atIndex:(int)index;
-(Tires *) tireAtIndex:(int) index;
-(void)print;
@end
class Car.m
@implementation
//setter 方法setEngine:将实例变量engine的值设为方法参数所指向的值,实际上被复制的并不是engine本身,而是指向engine的指针值,例如指针 *p1,*p1->engine ,调用setter 方法后,会给engine自动复制一个指针*p2,同时,让 *p2->engine,所以,实质上还是只存在一个发动机;
-(void) setEngine:(Engine *)newEngine{
engine = newEngine;
}
//getter方法,在ObjectiveC中,所有对象间的交互都是通过指针实现的,所以方法返回一个指针,指向发动机对象;
-(Engine *) engine{
return engine;
}
//用到了防御式编程思想;
-(void) setTire:(Tires *)tire atIndex:(int)index{
if(index < 0 || index > 3){
NSLog(@"bad index %d in setTire:atIndex:",index);
exit(1);
}
tires[index] = tire;
}
-(Tires *) tireAtIndex: (int)index{
if(index < 0
|| index > 3){
NSLog(@"bad index %d in tireAtIndex:",index);
exit(1);
}
return tires[index];
}
-(void) print{
NSLog(@"%@",engine);
NSLog(@"%@",tires[0]);
NSLog(@"%@",tires[1]);
NSLog(@"%@",tires[2]);
NSLog(@"%@",tires[3]);
}
@end
main:
int main(int argc, const char * arcv[]){
Car *car = [Car new];
//申请一个车子的框架,什么都没有;
Engine *engine = [Engine new];//申请一个发动机;
[car setEngine:engine];//为这辆车装备上发动机;
int i;
for (i = 0; i < 4; i++){ //申请四个轮胎;
Tire *tire = [Tire new];
[car setTire:tire atIndex:i]; //为这辆车装备上四个轮胎;
}
[car print];
return 0;
}
程序到这里就全部结束了,两次的运行结果完全相同,但是,有没有觉得后面的代码会更容易理解呢,Car中的初始化init方法没有了,取而代之的是 setter 方法,更容易理解些;