0.前言
Objective-C中,访问对象的实例变量一般用setter和getter属性方法读取,利用property关键字和synthesize关键字可以方便地告知编译器生成这两个属性方法。我们将通过一个person类的示例进行讲解。
//person.h
#import
@interface Person : NSObject
{
int age;
}
-(void) setAge:(int) ag;
-(int) age;
@end
//person.m
@implementation Person
-(void) setAge:(int) ag
{
age=ag;
}
-(int) age
{
return age;
}
@end
1.property用法
(1)用property申明属性
通过property关键字可以方便地表明我们对象的成员变量属性,并自动生成setter和getter方法,自动生成生成的方法名为-setObjectname,-objectname。对person类进行改写
//person.h
@interface Person : NSObject
@property (nonatomic) age;
@end
//person.m
@implementation Person
@end
这两段代码是等价的,我们发现少了实例变量的申明,少了set和get方法的申明和实现。编译器发现property关键字后自动给我们创建了_age的实例变量,创建了-setAge和-age存取方法。那在property中修饰age的(nonatomic)是什么呢,这是属性特性,表示是非原子性,暂时不用太过关注,先看看property的一些注意点
(2)property与synthesize
如果我们自己实现了setter和getter方法中的一种,那么编译器会帮我们把剩下的另一种补上。但是如果你申明了一个属性,且手动实现了所需的存取方法,那么编译器不会合成实例变量,常用于依赖其他实例变量产生的属性
举例如下,给person增加一个beauty属性,与age的关系是beauty=3*age
//person.h
@interface Person : NSObject
@property (nonatomic) int age;
@property (nonatomic) int beauty;
@end
//person.m
@implementation Person
-(int) beauty
{
return (3*age);
}
- (void) setBeauty:(int)beauty
{
//_beauty=beauty; //**如果加上这句将会报错,不存在_beauty实例变量**
}
@end
此时,Person只有 _age 一个实例变量。通常我们会用@synthesize指令
//person.m
@implementation Person
@synthesize beauty=_beauty
-(int) beauty
{
return (3*age);
}
- (void) setBeauty:(int)beauty
{
_beauty=beauty; //此时存在_beauty实例变量
}
@end
来告诉编译器Person类中有一个 _beauty 的实例变量,是beauty属性的-setBeauty和-beauty的实例变量,如果它不存在,就将它创建出来。当然你可以改口叫她它
@synthesize beauty=_notBeauty;
只要记得用的时候用新名字就好
- (void) setBeauty:(int)beauty
{
_notBeauty=beauty; //此时存在_notBeauty实例变量
}
(3)属性特性
一般申明一个属性有以下几类
读写属性:
readonly
readwrite
原子性
atomic
nonatomic
内存管理
assign
copy
retain
unsafe_unretained
strong
weak
一般读写属性readonly指示系统只合成getter方法,不合成setter方法;readwrite是默认值,指示系统需要合成setter方法和getter方法。
原子性用于多线程访问实例变量,默认为atomic,读写时会有自旋锁,会降低性能,一般自己要显式添加nonatomic特性(《OC编程》作者认为atomic属性作用不大,见34.1atomic与nonatomic)。
内存管理来说:
assign
:常用于NSInteger等OC基础类型,以及short、int、double、结构体等C数据类型,因为这些类型不存在被内存回收的问题。delegate用assign修饰。
copy
:setter方法将传入的对象复制一份,副本给成员变量,相应的原先的被赋值的对象的引用计数加1,用于NSString,NSArray等类。
retain
:ARC机制下少用, 对象赋值给该属性时,原来引用的计数-1,现在的引用对象计数+1
strong
、weak
:strong指示符该属性对被赋值对象持有强引用,而weak指示符指定该属性对被赋值对象持有弱引用。强引用的意思是:只要该强引用指向被赋值的对象,那么该对象就不会自动回收。弱引用的意思是:即使该弱引用指向被赋值的对象,该对象也可能被回收。如果不希望对象被回收,可以使用strong指示符。如果需要保证程序性能,避免内存溢出,可以使用weak,内存一旦被回收,指针会被赋值为nil。
unsafe_unretained
:与weak不同,被unsafe_unretained指针所引用的对象被回收后,unsafe_unretained指针不会被赋为nil,可能会导致程序出错。