Objective-C语法@property详解

@Property是声明属性的语法,它可以快速方便的为实例变量创建存取器,并允许我们通过点语法使用存取器。

存取器(accessor):指用于获取和设置实例变量的方法。用于获取实例变量值的存取器是getter,用于设置实例变量值的存取器是setter。

原子性

nonatomic 非原子属性

atomic 原子属性–默认属性

原子属性就是针对多线程设计的。 原子属性实现 单(线程)写 多(线程)读
“atomic(原子属性)在set方法内部加了一把自旋锁”
“nonatomic(非原子属性)下,set和get方法都不会加锁”

原子属性内部使用的 自旋锁

自旋锁和互斥锁

共同点: 都可以锁定一段代码。 同一时间, 只有线程能够执行这段锁定的代码

区别:
互斥锁,在锁定的时候,其他线程会睡眠,等待条件满足,再唤醒
自旋锁,在锁定的时候, 其他的线程会做死循环,一直等待这条件满足,一旦条件满足,立马去执行,少了一个唤醒过程

一般iOS程序中,所有属性都声明为nonatomic

这样做的原因是:
在iOS中使用同步锁的开销比较大, 这会带来性能问题。一般情况下并不要求属性必须是“原子的”,因为这并不能保证“线程安全”(thread safety),若要实现“线程安全”的操作,还需采用更为深层的锁定机制才醒。
例如:一个线程在连续多次读取某个属性值的过程中有别的线程在同时改写该值,那么即便将属性声明为atomic,也还是会读取到不同的属性值。

因此,iOS程序一般都会使用nonatomic属性,但是在Mac OS X程序时, 使用atomic属性通常都不会有性能瓶颈

读/写权限

  • readwrite(读写) 编译器会自动生成gettersetter方法.
  • readonly(只读) 编译器会自动生成getter方法.
  • 如果既覆盖了存方法,也覆盖了取方法(或者只读属性覆盖了取方法),那么编译器不会创建相应的实例变量,如果需要,必须手动声明。

内存管理语义

以下修饰符只影响属性的setter方法

  • assgin 简单的赋值操作, 用来修饰(NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等)。
  • strong 保留新值,释放旧值,然后再将新值设置上去. 常用来修饰OC对象.
  • weak 与assign类似,用来修饰oc对象表示一种弱引用关系,属性所指的的对象销毁时,属性值会被清空.
  • unsafe_unretained 表弱引用,但是目标对象遭到摧毁时,属性值不会自动清空,unsafe的,易出现野指针.
  • copy 设置方法不保留新值,而是将其拷贝(copy), 保留拷贝的对象.常用来修饰含有可深拷贝的mutable子类的类,如NSArray,NSSet,NSDictionary,NSData的,NSCharacterSet,NSIndexSet,NSString.

strong为指针拷贝,copy为内容拷贝.

方法名

  • getter=<name> 用来指定getter方法的方法名,常见用法:
1
@property (assign,nonatomic,getter=isOn) BOOL on;
  • setter=<name> 同理用来指定setter方法的方法名,不太常见.