iOS開發(fā) nonatomic 和 atomic區(qū)別

在默認情況下,由編譯器所合成的方法會通過鎖定機制確保其原子性(atomicity)。如果屬性具備nonatomic特質(zhì),則不需要同步鎖。

如果兩個線程同時讀取一個屬性,那么不論何時,總能看到有效的屬性值。

如果不加鎖的話(或者說使用nonatomic語義),那么當(dāng)其中一個線程正在改寫某屬性值的時候,另外一個線程也許會突然闖入,把尚未修改好的屬性值讀取出來。發(fā)證這種情況時,線程讀取到的屬性值肯能不對。

在iOS中使用同步鎖的開銷比較大, 這會帶來性能問題。一般情況下并不要求屬性必須是“原子的”,因為這并不能保證“線程安全”(thread safety),若要實現(xiàn)“線程安全”的操作,還需采用更為深層的鎖定機制才醒。

例如:一個線程在連續(xù)多次讀取某個屬性值的過程中有別的線程在同時改寫該值,那么即便將屬性聲明為atomic,也還是會讀取到不同的屬性值。

因此,iOS程序一般都會使用nonatomic屬性。但是在Mac OS X程序時, 使用atomic屬性通常都不會有性能瓶頸。

因為看評論有人問了,所以補充個問題,就是atomic一定是線程安全的么,回答是NO :

nonatomic的內(nèi)存管理語義是非原子性的,非原子性的操作本來就是線程不安全,而atomic的操作是原子性的,但并不意味著他就是線程安全的,它會增加正確的幾率,能夠更好的避免線程錯誤,但仍舊是不安全的。

為了說atomic與nonatomic的本質(zhì)區(qū)別其實也就是在setter方法上的操作不同:

nonatomic的實現(xiàn):
'''

  • (void)setCurrentImage:(UIImage *)currentImage
    {
    if (_currentImage != currentImage) {
    [_currentImage release];
    _currentImage = [currentImage retain];

      // do something
    

    }
    }

  • (UIImage *)currentImage
    {
    return _currentImage;
    }
    '''
    atomic的實現(xiàn):
    '''

  • (void)setCurrentImage:(UIImage *)currentImage
    {
    @synchronized(self) {
    if (_currentImage != currentImage) {
    [_currentImage release];
    _currentImage = [currentImage retain];

          // do something
      }
    

    }
    }

  • (UIImage *)currentImage
    {
    @synchronized(self) {
    return _currentImage;
    }
    }
    '''
    Using the @synchronized Directive
    The @synchronized directive is a convenient way to create mutex locks on the fly in Objective-C code. The @synchronized directive does what any other mutex lock would do—it prevents different threads from acquiring the same lock at the same time. In this case, however, you do not have to create the mutex or lock object directly. Instead, you simply use any Objective-C object as a lock token, as shown in the following example:
    '''

  • (void)myMethod:(id)anObj
    {
    @synchronized(anObj)
    {
    // Everything between the braces is protected by the @synchronized directive.
    }
    }
    '''
    The object passed to the @synchronized directive is a unique identifier used to distinguish the protected block. If you execute the preceding method in two different threads, passing a different object for the anObj parameter on each thread, each would take its lock and continue processing without being blocked by the other. If you pass the same object in both cases, however, one of the threads would acquire the lock first and the other would block until the first thread completed the critical section.

As a precautionary measure, the @synchronized block implicitly adds an exception handler to the protected code. This handler automatically releases the mutex in the event that an exception is thrown. This means that in order to use the @synchronized directive, you must also enable Objective-C exception handling in your code. If you do not want the additional overhead caused by the implicit exception handler, you should consider using the lock classes.

For more information about the @synchronized directive, see The Objective-C Programming Language.

當(dāng)使用atomic時,雖然對屬性的讀和寫是原子性的,但是仍然可能出現(xiàn)線程錯誤:當(dāng)線程A進行寫操作,這時其他線程的讀或者寫操作會因為等該操作而等待。當(dāng)A線程的寫操作結(jié)束后,B線程進行寫操作,所有這些不同線程上的操作都將依次順序執(zhí)行——也就是說,如果一個線程正在執(zhí)行 getter/setter,其他線程就得等待。如果有線程C在A線程讀操作之前release了該屬性,那么還會導(dǎo)致程序崩潰。所以僅僅使用atomic并不會使得線程安全,我們還要為線程添加lock來確保線程的安全。

更準確的說應(yīng)該是讀寫安全,但并不是線程安全的,因為別的線程還能進行讀寫之外的其他操作。線程安全需要開發(fā)者自己來保證。

其實無論是否是原子性的只是針對于getter和setter而言,比如用atomic去操作一個NSMutableArray ,如果一個線程循環(huán)讀數(shù)據(jù),一個線程循環(huán)寫數(shù)據(jù),肯定會產(chǎn)生內(nèi)存問題,這個就跟getter和setter就木有關(guān)系了。

在豆瓣最近看到這篇文章感覺不錯 ,這是鏈接:https://www.douban.com/note/486901956/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內(nèi)容

  • Objective-C是一門動態(tài)的語言 ① 什么是動態(tài)語言? 動態(tài)語言,是指程序在運行時可以改變其結(jié)構(gòu):新的函數(shù)可...
    小李龍彪閱讀 376評論 0 0
  • 技術(shù) 最近正在準備換份工作, 看到網(wǎng)上有份題庫, 覺得不錯, 準備整理下, 復(fù)習(xí)下所學(xué)知識, 為面試做足準備, 下...
    火之玉閱讀 6,415評論 7 105
  • 我們聲明屬性的時候,必須要考慮到屬性特質(zhì)對編譯器所產(chǎn)生的存取方法的影響。 下面我們就主要講講atomic 與 no...
    你好8828閱讀 2,543評論 2 4
  • 接著上節(jié) mutex,本節(jié)主要介紹atomic的內(nèi)容,練習(xí)代碼地址。本文參考http://www.cplusplu...
    jorion閱讀 73,763評論 1 14
  • 《故事I》 幕前,幕后 沒有轉(zhuǎn)頭 離去的是風(fēng) 分開的是手 走 西湖泛起煙波 情便一發(fā)難收 走 靠近,接近 你的影,...
    飲雨閱讀 144評論 0 1