上一节的Appliance.h中声明了2个成员变量productName和voltage。如果不使用属性机制@property,就需要用以下代码声明存取方法:
- (void)setProductName:(NSString *)s;
- (NSString *)productName;
- (void)setVoltage:(int)x;
- (int)voltage;
使用属性机制后,代码如下:
@property (copy) NSString *productName;
@property int voltage;
而Applicance.m就更为麻烦,不使用属性机制的实现如下:
- (void)setProductName:(NSString *)s
{
productName = [s copy];
}
- (NSString *)productName
{
return productName;
}
- (void)setVoltage:(int x)
{
voltage = x;
}
- (int)voltage
{
return voltage;
}
而使用属性机制,则只有一句话:
@synthesize productName, voltage;
在Objective-C中,当编译iOS程序或64位Mac OS X程序时,可以不用声明实例变量。@property/@synthesize指令能够自动创建相应数据所需的内存空间。
注释掉Appliance.h中的变量声明,程序可以照常执行。
@interface Appliance : NSObject
{
//NSString *productName;
//int voltage;
}
属性的特性
存取类型
属性可以声明为readwrite或readonly,默认为readwrite
@property (readonly) int voltage;
生命周期类型
包括:unsafe_unretained, strong, weak和copy
unsafe_unretained是默认的类型,最为简单,存方法会将传入的值直接赋值给实例变量。非对象的实例变量都应该使用这种特性。
strong要求保留传入对象,并放弃原有对象,凡是只想对象的实例变量都应该使用strong特性。
weak特性要求不保留传入对象。相应的存方法会将传入的对象直接赋值给实例变量,如果该对象被释放,那么相应的实例变量会被自动赋为nil。
copy特性要求拷贝传入的对象,并将新对象赋值给实例变量。
@property (copy) NSString *lastName;
@synthesize lastName;
// 合成指令生成的代码等同于
- (void)setLastName:(NSString *)d
{
lastName = [d copy];
}
atomic与nonatomic,特性属于多线程编程的范畴。
KVC,key-value coding。让程序通过名称直接存取属性。这种方法常用于存取数据或者在使用CoreData存取数据时。如果输错了名称,编译器不会发出警告,但是在运行程序时会发生错误。
[a setProductName:@"Washing Machine"];
// KVC写法
[a setValue:@"Washing Machine" forKey:@"productName"];