小談@property的特質(zhì)

熟悉OC的小伙伴都會經(jīng)常用到property(屬性),屬性是OC語言的一種特性,主要作用是封裝對象中的數(shù)據(jù),OC對象通常會把所需要的數(shù)據(jù)保存為各種實例變量。實例變量一般通過存取方法(access method)來訪問。
使用屬性時又一個問題需要注意:就是屬性后面會經(jīng)常附帶一些特質(zhì)(attribute),區(qū)分好每一種特質(zhì)的作用是非常必要的。
例如下面的代碼就有三種特質(zhì):

@property (nonatomic, copy, readonly) NSString * aString;

屬性的特質(zhì)主要分為以下四類:

1.原子性

在默認情況下,由編譯器所合成的方法會通過鎖定機制確保其原子性(atomicity)。如果屬性具備nonatomic特質(zhì),則不需要使用同步鎖。與nonatomic對應的是atomic。注意:盡管沒有命名為atomic的特質(zhì),扔可以在屬性的特質(zhì)中寫atomic的聲明,編譯器也不會報錯。若是自己定義屬性的存取方法,就應該遵循屬性的特質(zhì)。
具備atomic特質(zhì)的屬性的獲取方法會通過鎖定機制來確保其操作的原子性。也就是說,如果有兩個線程讀寫同一個屬性,那么不論何時都能有效的屬性值。如果時nonatomic特質(zhì)(不加鎖)的屬性,當其中一個線程在改寫值時,另一個線程也會突然闖入,把尚未修改好的屬性值讀取出來,這種情況下讀取出來的值有可能是錯誤的。但是atomic特質(zhì)會對系統(tǒng)能耗較大,屬性常用nonatomic,也是默認的特質(zhì)。

2.讀/寫權(quán)限

  • 讀&寫:具備readwrite特質(zhì)的屬性擁有獲取方法(getter)設置方法(setter),如果屬性由@synthesize實現(xiàn),則編譯器會自動生成這兩個方法(雖然再Xcode中看不見,但是可以直接使用)
  • 只讀:具備readonly特質(zhì)的屬性將只擁有獲取方法(getter),只有在屬性由@synthesize實現(xiàn)時,編譯器才會為其合成獲取方法。

3.內(nèi)存管理

屬性用于封裝數(shù)據(jù),而數(shù)據(jù)需要有具體的所有權(quán)語義(concrete ownership semantic),下面這些會影響屬性的設置方法(setter)

  • assign 設置方法只會執(zhí)行針對`純量類型·(比如:NSInteger,CGFloat,int等)的操作。

  • strong 此特性表明了屬性定義了一種擁有關(guān)系(owning relationship)。為這種屬性設置新的值時,設置方法會先保留新值,并釋放舊值,然后再將新值賦值上去。

    - (void)setName:(NSString *)newName {
        NSString *tmp = newName;
        [_oldName release];
        _oldName = tmp;
    }
  • weak 此特質(zhì)表明了屬性定義了一種非擁有關(guān)系(nonowning relationship)。為這種屬性設置新值時,設置方法既不保留新值也不釋放舊值。此特質(zhì)與assign 類似,然而在屬性所對應的對象被釋放時,屬性的值會設置為nil。

  • unsafe_unretaind 此特質(zhì)的定義與assign特質(zhì)相同,不同的是它適用于對象類型(object type),該特質(zhì)表明了一種不保留關(guān)系(unretained),當所指對象被釋放時,屬性不會自動設置為nil(不安全 unsafe),這一點與weak區(qū)分。

  • copy 此特質(zhì)所表達的所屬關(guān)系與strong類似,不同的是其設置方法不會保留新值,而是將新值拷貝(copy)。屬性類型是NSString時經(jīng)常用此特質(zhì)來保護其封裝性,因為傳遞給設置方法的新值可能指向一個NSMutableString類的實例,此時如果不拷貝字符串,那么設置完屬性之后,字符串的值可能在對象不知情的情況下被人修改。所以此時需要拷貝(copy)一份不可變的字符串,確保對象中的值不會不經(jīng)意間變動。只要實現(xiàn)屬性所用的對象是可變的,就應該在設置新值時拷貝(copy)一份。

4.方法名

可通過如下特質(zhì)來制定獲取方法設置方法的名稱。

  • getter=<name> 此特質(zhì)用來指定獲取方法的名稱。如果屬性時BOOL值,而你想為其獲取方法加上is前綴,就可以用這個特質(zhì)來指定,編譯器就會為你合成獲取方法。
@prpperty (getter=isAuth) BOOL auth;
  • setter=<name> 此特質(zhì)涌來指定設置方法的名稱,用的不常見。

over。

參考

《Effective Objective-C》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容