Objective-C @property属性

@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 是内容拷贝。