寫個小文章簡單闡述iOS開發(fā)中@property的特性問題。
@Property是聲明屬性的語法掠哥,它可以快速方便的為實例變量創(chuàng)建存取器巩踏,并允許我們通過點語法使用存取器。
每個@property屬性都含有特性(attribute)续搀,用來描述響應(yīng)存取方法的行為塞琼,這些特性需要寫在小括號里。任何@property屬性都有特性禁舷,每個特性都有不同的可選類型彪杉,每種特性中都有一項是默認(rèn)的。如果使用默認(rèn)特性則不用在括號中表明牵咙。
1.多線程特性
多線程特性有兩種可選類型:nonatomic 和 atomic派近,其中后者為默認(rèn)特性。但因atomic這種線程保護技術(shù)很耗費資源洁桌,在iOS開發(fā)中一般使用nonatomic特性构哺。
- atomic:默認(rèn)是有該屬性的,這個屬性是為了保證程序在多線程情況战坤,編譯器會自動生成一些互斥加鎖代碼曙强,避免該變量的讀寫不同步問題。
- nonatomic:如果該對象無需考慮多線程的情況途茫,請加入這個屬性碟嘴,這樣會讓編譯器少生成一些互斥加鎖代碼,可以提高效率囊卜。
2.讀/寫特性
readwrite娜扇、readonly這兩個屬性的價值错沃,不是提供成員變量訪問接口,而是控制成員變量的訪問權(quán)限雀瓢。
- readwrite:這個屬性是默認(rèn)的情況枢析,會自動為你生成存取器。
- readonly:只生成getter不會有setter方法刃麸。
3.內(nèi)存管理特性
內(nèi)存管理特性的類型可以決定相應(yīng)的實例變量將如何引用對象醒叁。
- assign:默認(rèn)類型,setter方法直接賦值泊业,不進行任何retain操作把沼,不改變引用計數(shù)。該方法只會針對“純量類型”(CGFloat或NSInteger等)和C數(shù)據(jù)類型(int, float, double, char, 等等)的簡單賦值操作吁伺,id類型也要用assign饮睬,所以一般iOS中的代理delegate屬性都會用assign來標(biāo)示。
- strong:強引用篮奄,其存亡直接決定了所指向?qū)ο蟮拇嫱隼Τ睢J褂迷撎匦詫嵗兞吭谫x值時,會釋放舊值同時設(shè)置新值窟却,對對象產(chǎn)生一個強引用昼丑,即引用計數(shù)+1。如果不存在指向一個對象的引用间校,并且此對象不再顯示在列表中矾克,則此對象會被從內(nèi)存中釋放。
- weak:弱引用憔足,不決定對象的存亡胁附。屬性表明了一種”非擁有關(guān)系“,既不釋放舊值滓彰,也不保留新值控妻,即引用計數(shù)不變,當(dāng)指向的對象被釋放時揭绑,該屬性自動被設(shè)置為nil弓候。即使一個對象被持有無數(shù)個弱引用,只要沒有強引用指向它他匪,那么還是會被清除菇存。
- copy:和strong類似,不過該屬性會被復(fù)制一個新的副本邦蜜。很多時使用copy是為了方式Mutable(可變類型)在我們不知道的情況下修改了屬性值依鸥,而用copy可以生成一個不可變的副本防止被修改。如果我們自己實現(xiàn)setter方法的話悼沈,需要手動copy贱迟。
用 @property 聲明 NSString姐扮、NSArray、NSDictionary 經(jīng)常使用 copy 關(guān)鍵字衣吠,是因為他們有對應(yīng)的可變類型:NSMutableString茶敏、NSMutableArray、NSMutableDictionary缚俏,他們之間可能進行賦值操作惊搏,為確保對象中的字符串值不會無意間變動,應(yīng)該在設(shè)置新屬性值時拷貝一份袍榆。 - unsafe_unretained:和weak一樣胀屿,唯一的區(qū)別就是當(dāng)對象被釋放后塘揣,該屬性不會被設(shè)置為nil包雀。所以是unsafe的。
4.方法名特性
方法名可以修改為我們合成的方法名亲铡,可以使存取方法語義更加符合應(yīng)用場景才写。