通常我们定义一个类的属性时会为其编写set与get方法,而当属性越来越多时,set与get方法在代码的编写中也占了很大一部分,于是就有了@property指令。
//最多拥有三类关键字,不分先后顺序,用“,”分隔,缺省时使用默认值。
@property(关键字1,关键字2,关键字3) NSObject * object;
通常使用了@property后会在编译后产生一个私有变量_object,一个set方法,一个get方法。
关于私有变量_object
使用@property实际并不会产生一个叫object的对象,而是系统为我们生产的前面带下划线的_object。
是因为编译器在.h文件中还为我们生成了一条语句:
(Xcode4.5以前的版本中我们需要自己编写,这一福利改变来自于一封至Apple的公开信)
@synthesize object = _object;
所以默认情况下生成的私有对象都是下划线+属性名,但是如果不想用系统为我们生成的名字时,可以重写它(虽然这没多大意义):
<span style="font-size:12px;">@synthesize object = obj;</span>
由于_object是私有变量,所以我们可以直接通过_object来获取对象。也可以使用self.object(通过其对应的set与get方法来获得_object对象,在等号左侧调用set方法,等号右侧调用get方法)来获取对象,他们最终的操作对象都是_object。
最好不要直接使用_object来进行赋值等操作,虽然代码上能省略一点,但是这会使定义@property时使用的关键字失去意义,因为关键字影响的不是_object对象,而是它的set与get方法。
MRC下关键字的使用
关键字1:赋值(assign(默认)、retain、copy)
assign:对属性直接赋值,相当于值传递,无关引用计数,通常用于基本数据类型。因为基本数据类型不是对象,没有对象方法或类方法,更没有retain()和release ()方法。
//使用assign关键字对应的set方法
- (void)setObject:(NSObject *)object{
_object = object;//对变量直接赋值
}
retain:引用计数+1,相当于指针拷贝,_object对象指向赋值对象的地址//使用retain关键字对应的set方法
- (void)setObject:(NSObject *)object{
if (_object!=object) {
[_object release];
_object = [object retain];<span style="font-family: Arial, Helvetica, sans-serif;">//object与_object指向的是同一个对象
}
}
copy:将object拷贝一份,相当于内容拷贝,位于新的内存空间,引用计数=1,原对象的引用计数不变,通常用于NSString。
//使用retain关键字对应的set方法
- (void)setObject:(NSObject *)object{
if (_object!=object) {
[_object release];
_object = [object copy];
}
}
关键字2:原子性(atomic(默认)、nonatomic)
atomic:多线程下,存在线程保护。
nonatomic:多线程下,不存在线程保护,
atomic为set/get方法增加互斥锁,即当多个线程同时访问set或get方法时,必须排队,且上一个线程离开后下一个线程才能进来。是防止在写未完成的时候被另外一个线程读取,造成数据错误。这种安全性的提升是以额外消耗系统资源为代价。所以如当对属性的访问不需要多线程支持时,通常使用nonatomic,因为它执行率相对快些。
关键字3:读写性(readwrite(默认)、readonly)
readwrite:支持读写,为属性生成set与get方法。
readonly:只能读,属性只生成get方法。
ARC下新增关键字的使用
关键字:赋值(strong(默认)、weak)
原有关键字不变的情况下,在ARC下新引入了strong 与weak关键字(代替retain和assign)。
strong:表示强引用,相当与MRC下的retain。
区别:在ARC下,NSString使用strong后会自动转为copy。
weak:表示弱引用,相当与MRC下的assign。
区别:weak相对assign而言,当对象消失后,不再成为野指针,而是会自动指向nil对象。好处是:如果对野指针发送消息会导致程序崩溃,而对nil对象发消息不会。
(在ARC下,除了对property属性声明它使strong还是weak外,还可以为局部变量声明强弱,使用(两个下划线)__weak与__strong(默认)关键字 例:__weak id name;)