[OC]之 atomic 與 nonatomic的區(qū)別

我們聲明屬性的時候衙伶,必須要考慮到屬性特質(zhì)對編譯器所產(chǎn)生的存取方法的影響。

下面我們就主要講講atomic 與 nonatomic:

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

請注意!<闹ⅰIぁ!盡管沒有名為atomic的特質(zhì)(如果某屬性不具備nonatomic特質(zhì)瘸爽,那它就是“原子的”(atomic))您访,但是仍然可以在屬性特質(zhì)中寫明這一點,編譯器是不會報錯的剪决。

那么atomic與nonatomic的區(qū)別又是什么捏灵汪?

之前說過滴檀训,具備atomic特質(zhì)的獲取方法會通過鎖定機制來確保其操作的原子性。

也就是說享言,如果兩個線程同時讀取一個屬性峻凫,那么不論何時,總能看到有效的屬性值览露。

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

相信大家都遇到過上述那種情況吧脐恩。。侦讨。驶冒。

一般iOS程序中,所有屬性都聲明為nonatomic韵卤。這樣做的原因是:

在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來確保線程的安全。

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末溺欧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子柏肪,更是在濱河造成了極大的恐慌姐刁,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烦味,死亡現(xiàn)場離奇詭異聂使,居然都是意外死亡,警方通過查閱死者的電腦和手機谬俄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門柏靶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事”怪埽” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵梆靖,是天一觀的道長控汉。 經(jīng)常有香客問我,道長返吻,這世上最難降的妖魔是什么姑子? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮测僵,結(jié)果婚禮上街佑,老公的妹妹穿的比我還像新娘。我一直安慰自己捍靠,他們只是感情好沐旨,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著榨婆,像睡著了一般磁携。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上良风,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天谊迄,我揣著相機與錄音,去河邊找鬼烟央。 笑死统诺,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的疑俭。 我是一名探鬼主播粮呢,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼钞艇!你這毒婦竟也來了啄寡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤哩照,失蹤者是張志新(化名)和其女友劉穎挺物,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葡秒,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年嵌溢,在試婚紗的時候發(fā)現(xiàn)自己被綠了眯牧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡赖草,死狀恐怖学少,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情秧骑,我是刑警寧澤版确,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布扣囊,位于F島的核電站,受9級特大地震影響绒疗,放射性物質(zhì)發(fā)生泄漏侵歇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一吓蘑、第九天 我趴在偏房一處隱蔽的房頂上張望惕虑。 院中可真熱鬧,春花似錦磨镶、人聲如沸溃蔫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伟叛。三九已至,卻和暖如春脐嫂,著一層夾襖步出監(jiān)牢的瞬間统刮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工雹锣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留网沾,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓蕊爵,卻偏偏與公主長得像辉哥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子攒射,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

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

  • Objective-C是一門動態(tài)的語言 ① 什么是動態(tài)語言醋旦? 動態(tài)語言,是指程序在運行時可以改變其結(jié)構(gòu):新的函數(shù)可...
    小李龍彪閱讀 361評論 0 0
  • 技術(shù) 最近正在準(zhǔn)備換份工作, 看到網(wǎng)上有份題庫, 覺得不錯, 準(zhǔn)備整理下, 復(fù)習(xí)下所學(xué)知識, 為面試做足準(zhǔn)備, 下...
    火之玉閱讀 6,401評論 7 105
  • 在默認(rèn)情況下会放,由編譯器所合成的方法會通過鎖定機制確保其原子性(atomicity)饲齐。如果屬性具備nonatomic...
    noahjill閱讀 884評論 0 0
  • 接著上節(jié) mutex,本節(jié)主要介紹atomic的內(nèi)容咧最,練習(xí)代碼地址捂人。本文參考http://www.cplusplu...
    jorion閱讀 73,584評論 1 14
  • Java8張圖 11、字符串不變性 12矢沿、equals()方法滥搭、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,693評論 0 11