2.2 使用@Property创建存取器
// Car.h
#import <foundation foundation.h="">
@interface Car : NSObject{
// 实例变量
NSString *carName;
NSString *carType;
}
@property(nonatomic,strong) NSString *carName;
@property(nonatomic,strong) NSString *carType;
@end</foundation>
上面代码中,我们使用@property声明两个属性,名称与实例变量名称相同(让我们先忽略nonatomic和strong)。
// Car.m
#import "Car.h"
@implementation Car
@synthesize carName;
@synthesize carType;
@end
在.m文件中我们使用@synthesize自动生成这两个实例变量的存取器,并且隐藏了存取器,虽然我们看不到存取器,但它们确实是存在的。
// main.m
int main(int argc, char * argv[]){
@autoreleasepool {
Car *car = [[Car alloc] init];
car.carName = @"Jeep Compass";
car.carType = @"SUV";
NSLog(@"The car name is %@ and the type is %@",car.carName,car.carType);
}
return 0;
}
在上面的代码中我们可以注意到,Car对象使用点语法给存取器发送消息,并且get与set的语法是相同的,所以这里的点语法可以根据语境判断我们是要赋值还是取值。
当然我们也依然可以使用消息语法来使用:
// main.m
int main(int argc, char * argv[]){
@autoreleasepool {
Car *car = [[Car alloc] init];
// 点语法
// car.carName = @"Jeep Compass";
// car.carType = @"SUV";
// NSLog(@"The car name is %@ and the type is %@",car.carName,car.carType);
// 消息语法
[car setCarName:@"Jeep Compass"];
[car setCarType:@"SUV"];
NSLog(@"The car name is %@ and the type is %@",[car carName],[car carType]);
}
return 0;
}
上面两段代码的执行结果都是:
1 The car name is Jeep Compass and the type is SUV
总结:@property等同于在.h文件中声明实例变量的get/set方法,@synthesize等同于在.m文件中实现实例变量的get/set方法。使用@property和synthesize创建存取器要比手动声明两个存取方法(getter和setter)更简单。而且我们在使用属性时可以使用点语法赋值或取值,语法更简单,更符合面向对象编程。
3.不必单独声明示例变量
如果使用@Property,就不必单独声明实例变量了。因为在没有显示提供示例变量声明的前提下,系统会自动帮你生成实例变量
// Car.h
#import <foundation foundation.h="">
@interface Car : NSObject
@property(nonatomic,strong) NSString *carName;
@property(nonatomic,strong) NSString *carType;
- (NSString *)carInfo;
@end
在.h文件中我们并没有声明实例变量,只是声明了carName和carType两个属性,以及一个carInfo方法,返回值为NSString *。
// Car.m
#import "Car.h"
@implementation Car
- (NSString *)carInfo{
return [NSString stringWithFormat:@"The car name is %@ and the type is %@",_carName,_carType];
}
@end
在.m文件中我们可以注意到,在carInfo方法中我们使用了_carName和_carType实例变量,这就是当我们没有显示声明实例变量时,系统为我们自动生成的。命名规则是以_为前缀,加上属性名,即_propertyName。
其实在.m文件中实际是存在@synthesize声明语句的,只是系统将其隐藏了:
@synthesize carName = _carName;
@synthesize carType = _carType;
那么如果我们不喜欢默认的实例变量命名方法,或者我们希望使用更有语义的名称,应该怎么做呢。其实很简单:
// Car.m
#import "Car.h"
@implementation Car
@synthesize carName = i_am_car_name;
@synthesize carType = i_am_car_type;
- (NSString *)carInfo{
return [NSString stringWithFormat:@"The car name is %@ and the type is %@",i_am_car_name,i_am_car_type];
}
@end
通过上述代码可以看到,我们只需要通过@synthesize来声明我们希望的实例变量名。
总结:如果我们希望使用默认的实例变量命名方式,那么我们在.m文件中就不需要使用@synthesize声明,系统会帮我们自动完成。如果我们希望自己命名实例变量命,那么我们就使用@synthesize显示声明我们希望的实例变量名。