属性参数的分类:1读写属性(readwrite/readonly)2内存管理(assign/retain/copy)(strong)3.原子性(atomicity/nonatomic)
1.读写属性
readwrite 可以读写,就有setter又有getter , readonly只有getter“没有setter”
2.内存管理
(1)assign 使用范围:非NSObject子类对象,基本数据类型如 NSinteger、CGfloat、int、char等
内存计数:直接赋值,retaincount不改变
(2)retain 使用范围: 只适用于NSObject对象,不适用于基本类型和corefoundation(一组c语言接口)因为这两种类型没有retaincount
内存计数:retaincount + 1
赋值时先结后离
- (void)setName:(NSString *)str
{
[str retain];
[name release];
name = str;
}
(3)copy:对象的拷贝,新申请一块内存空间,并把原始内容复制到那片空间.
使用范围: 可变的数据类型(nsmutable), 官方SDK中NSString和NSArray都是用copy,
内存计数:新对象的retaincount为1
一般我们都用strong
3.原子性
nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。
注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级。
tomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所 以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。
扩展一下
(1)retain + readonly 一起使用
看官方的SDK 会发现经常 @property(nonatomic,readonly,retain) UIView *contentView;
readonly 就应该已经没有setter的方法何必要加个retain呢
就我理解,readonly其实是有setter方法的(不set 它怎么会有值呢)
而这个setter方法只是在内部使用的外部不能对值进行修改即外部禁止写操作,
所以设置retain有意思的。
详情参考http://www.cocoachina.com/bbs/read.php?tid=91354&keyword=readonly
(2)(官方SDK,对NSString属性的定义都是用copy,而不是retain)
这样写得目的是怕你赋值的是一个MutableString,而MutableString是可变了,如果只是retain,
那么当你在外面改变了这个值的时候,你的属性的值也改变了