OC屬性&修飾符理解

OC屬性

[toc]

屬性的作用

1. 為成員變量提供訪問的接口。setter和 getter 方法

@property 與 @synthsize 搭配使用,當(dāng)你沒有實(shí)現(xiàn)屬性的setter和 getter方法時(shí),系統(tǒng)會(huì)默認(rèn)幫助生成Setter getter。

  • @synthSize var = _var;

    如果沒有生成set、get方法,則默認(rèn)幫助生成訪問器方法。在iOS4.4以前需要搭配@property使用,4.4以后@property不需要顯示聲明@synthsize即可生成訪問器方法。

  • @dynamic var;

    聲明dynamic以后將由程序員自己生成set/get方法,并且如果沒有實(shí)現(xiàn)不會(huì)觸發(fā)警告,如果真沒有實(shí)現(xiàn)而又調(diào)用了該屬性,則會(huì)導(dǎo)致crash

2. 屬性修飾符

  1. nonatomic/atomic

    1. nonatomic
      • 線程不安全 多個(gè)線程可以同時(shí)對其進(jìn)行訪問,沒有資源保護(hù)
      • 訪問速度快
    2. atomic
      • 線程安全 在多線程中只能有一個(gè)線程對進(jìn)行訪問,會(huì)默認(rèn)會(huì)setter方法加鎖(MRC環(huán)境重寫Setter方法需要設(shè)置訪問鎖)
      • 訪問效率慢
  2. assign/weak

    1. assign
      • 修飾基本數(shù)據(jù)類型(非指針型變量)setter方法里不會(huì)進(jìn)行任何retain操作
      • assign如果拿來修飾對象類型會(huì)有野指針(懸垂指針)的危險(xiǎn)。(MRC使用unsafe_unretained修飾對象類型).assign修飾對象的話,如果對象釋放了不會(huì)置為nil|
    2. weak
      • 修飾對象類型。Arc下使用 和assign的效果一致
      • weak比assign優(yōu)化的一點(diǎn)是,當(dāng)對象釋放了以后可以將修飾的指針置為nil,可以有效避免野指針的行為
  3. copy / Strong / Retain

討論copy 需要補(bǔ)充一下 深拷貝|淺拷貝 的知識

// 結(jié)論
// 1.容器類型的指針 copy 只會(huì)產(chǎn)生不可變對象, mutableCopy 只會(huì)產(chǎn)生可變對象 與指針本身可變性無關(guān)
// 2.容器類型的指針 copy/mutableCopy 只是對數(shù)組內(nèi)部元素指針的復(fù)制,不會(huì)去調(diào)用元素的copy方法,所以copy后新容器內(nèi)部的元素內(nèi)容是不變的。
  • copy
// 系統(tǒng)引用計(jì)數(shù)的默認(rèn)實(shí)現(xiàn)
- (void)setName:(NSString *)newname {
    if (_name != newname) {
        [_name release];
        _name = [newname copy];
    }
}
由上可以看出:
1. copy 修飾符 會(huì)先對舊對象release,然后copy一份新對象。因此會(huì)對引用計(jì)數(shù)進(jìn)行+1
2. copy 修飾符的特點(diǎn)就是會(huì)對對象進(jìn)行一次copy。
  • strong
// 系統(tǒng)引用計(jì)數(shù)的默認(rèn)實(shí)現(xiàn)
- (void)setName:(NSString *)newname {
   if (_name != newname) {
       [_name release];
       _name = [newname retain];
   }
}
由上可以看出: **strong 修飾符 會(huì)先對舊對象release,然后賦值并對新對象reatin。也會(huì)對引用計(jì)數(shù)進(jìn)行+1**
  • retain
    retain 是MRC時(shí)代的產(chǎn)物,retain的實(shí)現(xiàn)和strong是一樣的,因此strong 也可以用于MRC下。

特別注意:對于NSArray,NSDictionary,NSString這樣的不可變對象我們需要使用copy來修飾,如果使用了strong,則對象被賦值了一個(gè)可變對象的時(shí)候,不可變對象的內(nèi)容就可以發(fā)生改變了.容易造成語義的矛盾,也極有影響代碼的運(yùn)行。

  1. readonly/readwrite

    readwrite就是可讀寫,不加這個(gè)屬性修飾符默認(rèn)就是如此,所有變量都是可以讀寫的,也就是都自帶setter和getter方法,而使用readonly修飾系統(tǒng)會(huì)自動(dòng)生成getter方法而不生成setter方法所以是只讀的,無法賦值。

3.另外一些標(biāo)示符

  1. const

    NSString const *str = @"123";
    NSString * const str1 = @"123";
    str = @"456"; // 這句話只是把456的內(nèi)存地址分配給str 
    str 本身是一個(gè)變量,但它指向的內(nèi)存是不可變的
    str1 本身是一個(gè)常量,*str1 是一個(gè)變量
    

    const 相比 宏定義define:

     1. const 在編譯階段參與編譯,宏則是在預(yù)編譯階段
     2. 宏不做類型檢查,只是替換內(nèi)容,const 會(huì)編譯檢查類型
     3. 宏可以定義函數(shù)方法代碼塊,const不行
    
  2. static
    static 修飾的變量都是在字符常量區(qū)

    1. static 修飾全部變量
      • 限制了全局變量的作用域?yàn)楫?dāng)前文件內(nèi)
    2. static 修飾局部變量
      • 讓局部變量只初始化一次
      • 局部變量在程序中只有一份內(nèi)存
      • 并不會(huì)改變局部變量的作用域,僅僅是改變了局部變量的生命周期
  3. extern

    對extern來說,可以理解為擴(kuò)展吧,將當(dāng)前變量的作用域從一個(gè)類擴(kuò)展到另一個(gè)類。

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

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

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