有关类的属性的操作
存在的原因
对于property
一般来说,访问器(Accessor)包含我们操作一个属性所需要的setter和getter方法,为其他的类提供一个“接口”。使用@property
声明的属性会自动去声明该属性的访问器,无须我们手动创建。在@interface ……@end
区域中使用。
对于@synthesize
我们常见的使用就是@synthesize student = _student;
和@synthesize student;(等价于@synthesize student = student)
而@synthesize student = ???;
的作用就是使用???
这个变量代替student
这个属性来进行操作。哪为什么要这样操作呢?因为如果我们直接使用 用property
声明的属性实质上是通过该属性的Accessor来操作,该属性的引用计数会随着不同的操作而改变。而通过再定义一个变量来操作该属性是不会通过其Accessor的,也就不会有引用计数的问题,更好地避免了内存泄露。
通常在@implemention……@end
中使用
@property前的修饰词
原子性
-
atomic(默认):atomic意为操作是原子的,意味着只有一个线程访问实例变量。atomic是线程安全的,至少在当前的访器上是安全的。默认的,但是很少使用。比较慢,这跟ARM平台和内部锁机制有关。
-
nonatomic: nonatomic跟atomic刚好相反。表示非原子的,可以被多个线程访问。它的速度比atomic快,但不能保证在多线程环境下的安全性,在单线程和明确只有一个线程访问的情况下广泛使用。
访问器控制
-
readwrite(默认):表示同时拥有setter和getter。
-
readonly: 表示只有getter没有setter。
有时候为了语意更明确可能需要自定义访问器的名字,最常见的是BOOL类型,比如标识View是否隐藏的属性hidden。可以这样声明
@property(nonatomic,getter = isHidden )BOOLhidden;
要注意修改setter或者getter的名字是存在副作用的,可能会使KVC和KVO无法正常工作。
内存管理
-
retain:意味着实例变量要获取传入参数的所有权。具体表现在setter中对实例变量先release然后将参数 retain之后传给它。
下面这段代码展示了retain类似的行为:*
-(void)setStuName:(NSString*)stuName {
if(_stuName!= stuName){
[_stuName release];
_stuName = [stuName retain];
}
}
-
assign(默认):用于值类型,如int、float、double和NSInteger,CGFloat等表示单纯的复制。还包括不存在所有权关系的对象,比如常见的delegate。
-
strong:伴随ARC引入的关键字,是retain的一个可选的替代。表示实例变量对传入的参数要有所有权关系即强引用。strong跟retain的意思相同并产生相同的代码,但是语意上更好更能体现对象的关系。
-
weak: 跟assign的效果相似,不同的是weak在对象被回收之后自动设置为nil。weak只能用在iOS 5或以后的版本,对于之前的版本,使用unsafe_unretained。
-
unsafe_unretained:weak的低版本替代。
-
copy:为实例变量保留一个自己的副本。
参考博客: