@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的區別在於,屬性所指的對象清空以後,屬性值並不會清空。
先簡單認知一下它們的特徵,更深刻的問題,在以後一篇中詳細研究。