@property能够说是每个iOS开发者最经常使用的一句代码,甚至没有之一。可是,在上古的Xcode 4.4时代以前,事情并非这个样子的。
当时的iOS开发者,每当须要一个属性的时候。老是须要写这么几句话:数据库
.h @property NSObejct *foo; .m @synthesize foo = _foo;
头文件中加上@property,那么编译器会自动添加下面一段代码:安全
- (NSObject *)foo; - (void)setFoo:(NSObject *)newFoo;
也就是属性的setter和getter的声明。atom
那么@synthesize就是对应等效地实现了setter和getter。线程
- (NSObject *)foo { return _foo; } - (void)setFoo:(NSObject *)newFoo { _foo = newFoo; }
而自从Xcode4.5开始,喜大普奔,开发者只须要使用一句code
@property NSObject *foo;
就能直接作完三件事:对象
生成一个_foo名称的成员变量;继承
声明foo属性的setter和getter方法;内存
默认实现声明的两个setter和getter方法;ci
那么在后来的Xcode中,@synthesize还有什么用处呢?
首先咱们在一个控制器中,老是须要使用self.view来操做控制器的view属性,而无法用_view成员变量来直接使用。这个就是由于咱们默认的成员变量的声明,是在.m中用@synthesize view = _view;这种格式来声明的。那么继承自UIViewcontorller天然是取不到.m中声明的成员变量。因而,咱们若是继承了一个父类,在用父类属性的成员变量时,就须要用@synthesize foo = _foo; 来在子类中使用。
然鹅其实还有一个相关的关键字,不多见。它就是@dynamic。
@dynamic 的意思就是跟系统说,不要建立 property 对应的成员变量(就是通常的 _someProperty),也不要自动生成 get/set 方法,同时不要报错,到在运行时我本身会来添加 get/set 方法。好比像 CoreData 的对象,有些属性并非用 _someProperty 存起来的,而是从数据库里读出来的。那么就不须要系统默认的 getter、setter,而是在运行时生成。开发
可是咱们在开发中,更多所写的,是这个样子
@property (nonatomic, weak) UIView *backgroudView;
那么括号里面的东西,到底又作了什么,一个好的开发者,决不能容忍本身写下的一段代码不知道它的真实做用。
实际上,在括号里的东西,叫作属性的attribute,特征,或者叫特质。一个属性能够拥有的attribute,能够有四种:
原子性有两个关键字,atomic和nonatomic,很好理解。原子性和非原子性。若是是atomic修饰的属性,那么在默认生成的setter和getter方法中,会经过锁定机制确保属性的atomicity。可是原子性是不能保证线程安全的,这个问题随意搜一下就有答案,再也不赘述。那么nonatomic天然就是不加锁的。
默认属性会添加readwrite,同时生成setter和getter,因此本质上是由@synthesize来实现的。
而readonly就是表明只生成getter方法,而只能读的属性显然没有意义,因此,readonly属性通常都须要在这个类的实现中直接使用实例变量赋值,或者在class extension中从新定义为读写属性。
这个很简单,就是使用getter=<name>或setter=<name>来指定方法名,用来更改默认的存取成员变量的方法名称,通常只是在BOOL类型属性时经常使用。
这个就是那个经久不衰的问题点。实际上,属性用来封装数据,可是数据自己须要有全部权,因此内存管理的关注点在于持有方式,而不须要关心使用方式。因此,内存管理关键字影响的是setter方法的实现,本质上,是成员变量对赋值的持有方式。
咱们暂时只研究ARC下的几个关键字,assign,strong,weak,copy和unsafe_unretained(没错,这个也是ARC支持的修饰)。
assign 适用于简单赋值操做,赋值时直接将原值覆盖,没有任何多余操做。
strong 实际和__strong同门。__strong是id类型和对象类型默认的全部权修饰符。因此,strong修饰符显然只能用在id类型和对象类型上。
weak 和strong是对应关键字,适用范围同strong同样,做用特征和assign相似,可是我的认为weak才是ARC的精髓所在。稍后展开讨论。
copy 这个修饰的结果和strong相似,可是它并不保留新值,而是copy一份,从新保存。这个特质常常用在NSString上保护其封装性。由于mutable类型一旦copy,就保存了当前这一份值储存,成为不可变的类型。
unsafe_unretained 这个不多见,由于它的特质同assign相同,可是使用与对象类型。它与weak的区别在于,属性所指的对象清空以后,属性值并不会清空。
先简单认知一下它们的特征,更深刻的问题,在以后一篇中详细研究。