1.@property 屬性
在我們聲明property這個關(guān)鍵字的時候例如:
@property (nonatomic, strong) NSMutableArray *dataArray;
這個時候默認(rèn)編譯器會幫我們聲明一個Ivar(帶下劃線的成員變量_dataArray),還有對應(yīng)的setter和getter方法,使用了property之后,就可以使用iOS中的點語法,可以通過self.dataArray來使用這個實例變量,實質(zhì)上也是調(diào)用了對應(yīng)的setter和getter方法。
@property的特性,@property還有一些關(guān)鍵字,它們都是有特殊作用的,比如上述代碼中的nonatomic,strong.我把它們分為三類,分別是:原子性,存取器控制,內(nèi)存管理。
原子性:
atomic(默認(rèn)):atomic意為操作是原子的,意味著只有一個線程訪問實例變量。atomic是線程安全的,至少在當(dāng)前的存取器上是安全的。但是并不意味著它是線程安全的,它會增加正確的幾率,能夠更好的避免線程的錯誤,但是它仍然是線程不安全的。它是一個默認(rèn)的特性,但是很少使用,因為比較影響效率,這跟ARM平臺和內(nèi)部鎖機制有關(guān)。
nonatomic:nonatomic跟atomic剛好相反。表示非原子的,可以被多個線程訪問。它的效率比atomic快。但不能保證在多線程環(huán)境下的安全性,在單線程和明確只有一個線程訪問的情況下廣泛使用。
存取器控制
readwrite(默認(rèn)):readwrite是默認(rèn)值,表示該屬性同時擁有setter和getter。
readonly: readonly表示只有g(shù)etter沒有setter。
有時候為了語意更明確可能需要自定義訪問器的名字:
@property (nonatomic, setter = mySetter:,getter = myGetter ) NSString *name;
最常見的是BOOL類型,比如標(biāo)識View是否隱藏的屬性hidden??梢赃@樣聲明:
@property (nonatomic,getter = isHidden ) BOOL hidden;
內(nèi)存管理
strong? ? ? ? ? ? ? 釋放舊對象將舊對象的值賦予輸入對象,再提高輸入對象的索引計數(shù)為1,此關(guān)鍵字經(jīng)常使用。
weak? ? ? ? ? ? ? ? 不增加引用計數(shù),不持有對象,因此也不能決定對象釋放? 對比assign 的一個好處是,當(dāng)對象消失時指針自動歸為nil
assign? ? ? ? ? ? ? 適用于基礎(chǔ)數(shù)據(jù)類型(NSInteger CGFloat...)不增加引用計數(shù)
copy? ? ? ? ? ? ? ? 建立一個索引計數(shù)為1 的對象然后釋放舊對象 此屬性只對那些實行了NSCopying協(xié)議的對象類型有效(NSString , Block)
如果聲明屬性的時候不顯式指定任何關(guān)鍵字的時候默認(rèn)的關(guān)鍵字分兩種,一種是基本數(shù)據(jù)類型的默認(rèn)關(guān)鍵字是atomic,readwrite,assign,第二種對于普通的OC對象,默認(rèn)關(guān)鍵字是atomic,readwrite,strong。
同時重寫setter/getter的問題:我們會發(fā)現(xiàn),當(dāng)我們同時重寫setter/getter時會報錯,為什么呢?這是因為當(dāng)我們同時重寫setter/getter時,編譯器自動添加的代碼@synthesize dataArray = _dataArray;失效,就不會自動為我們生成實例變量_dataArray了,setter/getter操作的對象就不存在了。所以我們要加上@synthesize dataArray = _dataArray;,手動指定setter/getter要操作的實例對象是_dataArray.
2.@synthesizer
實現(xiàn)property所聲明的方法的定義。其實說直白就像是:property聲明了一些成員變量的訪問方法,synthesize則定義了由property聲明的方法。
他們之前的對應(yīng)關(guān)系是:property 聲明方法 ->頭文件中申明getter和setter方法 synthesize定義方法 -> m文件中實現(xiàn)getter和setter方法。
@interface ViewController ()
@property (nonatomic, strong) UIButton *myButton;
@end
@implementation ViewController
@synthesize myButton ;
@synthesize 語句只能被用在 @implementation 代碼段中,@synthesize 還有一個作用,可以指定與屬性對應(yīng)的實例變量,例如@synthesize myButton = xxx;那么self.myButton其實是操作的實例變量xxx,而不是_myButton了。如果默認(rèn)沒寫@synthesize和 @dynamic都沒寫,那么默認(rèn)的就是@syntheszie var = _var;
3.@dynamic
@dynamic 告訴編譯器:屬性的 setter 與 getter 方法由用戶自己實現(xiàn),不自動生成。(當(dāng)然對于 readonly 的屬性只需提供 getter 即可)。假如一個屬性被聲明為 @dynamic var,然后你沒有提供 @setter方法和 @getter 方法,編譯的時候沒問題,但是當(dāng)程序運行到 instance.var = someVar,由于缺 setter 方法會導(dǎo)致程序崩潰;或者當(dāng)運行到 someVar = var 時,由于缺 getter 方法同樣會導(dǎo)致崩潰。編譯時沒問題,運行時才執(zhí)行相應(yīng)的方法,這就是所謂的動態(tài)綁定。
參考:
http://blog.eddie.com.tw/2010/12/08/property-and-synthesize/
http://www.cocoachina.com/bbs/read.php?tid=7322
http://www.cnblogs.com/pinping/archive/2011/08/03/2126150.html