@property
@property 是声明属性的语法,它可以快速方便的为实例变量创建存取器,并允许我们通过点语法使用存取器。
存取器(accessor):指用于获取和设置实例变量的方法。用于获取实例变量值的存取器是 getter,用于设置实例变量值的存取器是 setter。
创建存取器
1.手工创建存取器
@interface Car : NSObject
{
// 实例变量
NSString *carName;
}
// setter
- (void)setCarName:(NSString *)newCarName;
// getter
- (NSString *)carName;
@end
以上代码为声明一个实例变量,并对其声明 set/get 方法,即存取器。
@implementation Car
// setter
- (void)setCarName:(NSString *)newCarName
{
carName = newCarName;
}
// getter
- (NSString *)carName
{
return carName;
}
@end
以上则为对实例变量存取器的实现,存取器就是对实例变量进行赋值和取值,赋值方法以 set 开头,取值方法以实例变量名命名。
2.使用 @property 创建存取器
@interface Car : NSObject
@property (nonatomic, strong) NSString *carName;
@end
以上代码,即创建了 carName 的 set/get 方法,并且从 iOS7 更新之后,无需在 .m 文件中写入 @synthesize 关键字,系统会自动生成默认的 set/get 方法。
如果使用 @property,在 .h 文件中,就不必单独声明实例变量了,只需要声明属性,系统会自动生成实例变量,命名规则以 _ 为前缀,加上属性名,如,上述代码中的实例变量为 _carName。
@property 关键字
1.原子性
atomic(默认):意思是原子性,意味着只有一个线程访问实例变量,atomic 是线程安全的,至少在当前的存取器上是安全的。它是一个默认的特性,但是很少使用,因为比较影响效率,这跟ARM平台和内部锁机制有关。
nonatomic:表示的是非原子性,它的效率比 atomic 快。但不能保证在多线程环境下的安全性,在单线程和明确只有一个线程访问的情况下广泛使用。
2.存取器控制
readwrite(默认):表示该属性同时拥有 setter 和 getter。
readonly:只生成 getter 没有 setter 方法。
3.引用
strong:强引用,也是我们通常说的引用,其存亡直接决定了所指向对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示在列表中,则此对象会被从内存中释放。
weak:弱引用,不决定对象的存亡。即使一个对象被持有无数个弱引用,只要没有强引用指向它,那么还是会被清除。
4.内存管理
assign(默认):setter 方法直接赋值,不进行任何 retain 操作,不改变引用计数。一般用于处理基本数据类型,如 int、float、double 和 NSInteger,CGFloat 等表示单纯的复制。还包括不存在所有权关系的对象,比如常见的 delegate。
retain:释放旧的对象(release),将旧对象的值赋给新对象,再令新对象引用计数为1。
copy:与 retain 处理流程一样,先对旧值 release,再 copy 出新的对象,retainCount 为1.为了减少对上下文的依赖而引入的机制。
5.retain 与 copy 的区别:
Copy 其实是建立了一个相同的对象,而 retain 不是:
比如一个NSString 对象,地址为0×1111 ,内容为@”STR”,Copy 到另外一个NSString 之后,地址为0×2222 ,内容相同。
新的对象 retain 为1 ,旧有对象没有变化 retain 到另外一个 NSString 之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1。
总结:retain 是指针拷贝,copy 是内容拷贝。