iOS中atomic和nonatomic區(qū)別及內(nèi)部實(shí)現(xiàn)

前言

iOS開發(fā)中使用@property聲明屬性時(shí),經(jīng)常用到atomic與nonatomic兩個(gè)關(guān)鍵字

@property(nonatomic,strong)UIImage *icon;
@property(strong)UIImage *icon1;//不寫默認(rèn)atomic

atomic與nonatomicd的主要區(qū)別就是系統(tǒng)自動(dòng)生成的getter/setter方法不一樣

  • atomic系統(tǒng)自動(dòng)生成的getter/setter方法會(huì)進(jìn)行加鎖操作
  • nonatomic系統(tǒng)自動(dòng)生成的getter/setter方法不會(huì)進(jìn)行加鎖操作

atomic

系統(tǒng)生成的getter/setter方法會(huì)進(jìn)行加鎖操作,注意:這個(gè)鎖僅僅保證了getter和setter存取方法的線程安全.

因?yàn)間etter/setter方法有加鎖的緣故,故在別的線程來讀寫這個(gè)屬性之前,會(huì)先執(zhí)行完當(dāng)前操作.

例如:
線程1調(diào)用了某一屬性的setter方法并進(jìn)行到了一半,線程2調(diào)用其getter方法,那么會(huì)執(zhí)行完setter操作后,在執(zhí)行g(shù)etter操作,線程2會(huì)獲取到線程1 setter后的完整的值.

當(dāng)幾個(gè)線程同時(shí)調(diào)用同一屬性的setter、getter方法時(shí),會(huì)get到一個(gè)完整的值,但get到的值不可控.

例如:
線程1 調(diào)用getter
線程2 調(diào)用setter
線程3 調(diào)用setter
這3個(gè)線程并行同時(shí)開始,線程1會(huì)get到一個(gè)值,但是這個(gè)值不可控,可能是線程2,線程3 set之前的原始值,可能是線程2 set的值,也可能是線程3 set的值

atomic是線程安全的嗎?

不是,
很多文章談到atomic和nonatomic的區(qū)別時(shí),都說atomic是線程安全,其實(shí)這個(gè)說法是不準(zhǔn)確的.
atomic只是對(duì)屬性的getter/setter方法進(jìn)行了加鎖操作,這種安全僅僅是set/get 的讀寫安全,并非真正意義上的線程安全,因?yàn)榫€程安全還有讀寫之外的其他操作(比如:如果當(dāng)一個(gè)線程正在get或set時(shí),又有另一個(gè)線程同時(shí)在進(jìn)行release操作,可能會(huì)直接crash)

nonatomic

系統(tǒng)生成的getter/setter方法沒有加鎖
線程不安全,但更快
當(dāng)多個(gè)線程同時(shí)訪問同一個(gè)屬性,會(huì)出現(xiàn)無法預(yù)料的結(jié)果

內(nèi)部實(shí)現(xiàn)

下面我們新建一個(gè)nonatomic和一個(gè)atomic變量,并用代碼演示其內(nèi)部實(shí)現(xiàn)

//interface
@property(nonatomic,strong)UIImage *icon;//nonatomic
@property(strong)UIImage *icon1;//atomic

nonatomic對(duì)象setter和getter方法的實(shí)現(xiàn)


//mrc 環(huán)境
//implementation
@synthesize icon = _icon;

//set
-(void)setIcon:(UIImage *)icon
{
    if(_icon != icon)
    {
        [_icon release];
        _icon = [icon retain];
    }
}
//get
-(UIImage *)icon
{
    return _icon;
}

atomic對(duì)象setter和getter方法的實(shí)現(xiàn)

//mrc 環(huán)境
//implementation
@synthesize icon1 = _icon1;

//set
-(void)setIcon1:(UIImage *)icon1
{
    //同步代碼塊
    @synchronized (self) {
        
        if(_icon1 != icon1)
        {
            [_icon1 release];
            _icon1 = [icon1 retain];
        }
    }
}
//get
-(UIImage *)icon1
{
    UIImage *image = nil;
    //同步代碼塊
    @synchronized (self) {
        
        image = [[_icon1 retain] autorelease];
    }
    return image;
}

總結(jié)

  • atomic只是保證了getter和setter存取方法的線程安全,并不能保證整個(gè)對(duì)象是線程安全的,因此在多線程編程時(shí),線程安全還需要開發(fā)者自己來處理.

  • 關(guān)于選擇:atomic系統(tǒng)生成的getter、setter會(huì)保證get、set操作的安全性,但相對(duì)nonatomic來說,atomic要更耗費(fèi)資源,且速度要慢,故在iPhone等小型設(shè)備上,如果沒有多線程之間的通訊,使用nonatomic是更好的選擇

代碼地址:https://github.com/CoderZhuXH/MyBlogExample

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

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

  • 基礎(chǔ) 1. 為什么說Objective-C是一門動(dòng)態(tài)的語言? 2. 講一下MVC和MVVM,MVP? 3. 為...
    波妞和醬豆子閱讀 3,513評(píng)論 0 46
  • 網(wǎng)上轉(zhuǎn)載最多的一篇關(guān)于atomic的文章《ios atomic nonatomic區(qū)別》其中關(guān)于講解atomic的...
    打不死的小怪獸閱讀 7,856評(píng)論 5 20
  • 1.屬性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作...
    曾令偉閱讀 1,127評(píng)論 0 10
  • 1.項(xiàng)目經(jīng)驗(yàn) 2.基礎(chǔ)問題 3.指南認(rèn)識(shí) 4.解決思路 ios開發(fā)三大塊: 1.Oc基礎(chǔ) 2.CocoaTouch...
    扶光啟玄閱讀 5,186評(píng)論 0 13
  • 人生中很多你以為過不去的坎 那些曾有過的害怕與面對(duì)的所謂困惑 都會(huì)在你真正經(jīng)歷后明白 沒有什么大不了的 只要找到正...
    小麥air閱讀 172評(píng)論 0 0

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