從一道網(wǎng)易面試題淺談OC線程安全(轉(zhuǎn))

下面代碼會發(fā)生什么問題聚磺?
@property (nonatomic, strong) NSString *target;

dispatch_queue_t queue = dispatch_queue_create("parallel", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 1000000 ; i++) {
dispatch_async(queue, ^{
self.target = [NSString stringWithFormat:@"ksddkjalkjd%d",i];
});
}

當(dāng)時我把自定義的隊列看成了串行隊列坯台,然后回答:“沒錯呀”。后來一運行崩潰了……
面試后咧最,我就仔細回想捂人,敲了Demo,看看崩潰原因是啥矢沿。
正好試試小伙伴給我介紹的調(diào)試野指針的方法滥搭,XCode7以上才有的Address Sanitizer。
打開后發(fā)現(xiàn)是經(jīng)典的EXC_BAD_ACCESS錯誤捣鲸,以我淺薄的經(jīng)驗來看瑟匆,這種一般是對一個已釋放的內(nèi)存的對象再次發(fā)送消息出現(xiàn)的。


1503650160314466.jpg

再看看崩潰堆棧

噢栽惶,看來是對已釋放的對象再次發(fā)送了release信息愁溜。
我又留意到,這個對象是Strong修飾的外厂。
那么他的Setter方法在MRC上就相當(dāng)于

  • (void)setTarget:(NSString *)target { [target retain];//先保留新值 [_target release];//再釋放舊值 _target = target;//再進行賦值}
    那么什么時候會導(dǎo)致過多調(diào)用release呢冕象,因為這是個并行隊列+異步男旗。
    那么假如隊列A執(zhí)行到步奏2香罐,還沒到步驟3時疲酌,隊列B也執(zhí)行到步驟2刑巧,那么這個對象就會被過度釋放嗜闻,導(dǎo)致向已釋放內(nèi)存對象發(fā)送消息而崩潰仍翰。
    后來我想怎么可以修改這段代碼變?yōu)椴槐罎⒌哪兀?br> 1.使用串行隊列
    將set方法改成在串行隊列中執(zhí)行就行钧嘶,這樣即使異步躁倒,但所有block操作追加在隊列最后依次執(zhí)行幔亥。
    2. 使用atomic
    atomic關(guān)鍵字相當(dāng)于在setter方法加鎖耻讽,這樣每次執(zhí)行setter都是線程安全的,但這只是單獨針對setter方法而言的狹義的線程安全帕棉。
    3.使用weak關(guān)鍵字
    weak的setter沒有保留新值或者保留舊值的操作针肥,所以不會引發(fā)重復(fù)釋放。當(dāng)然這個時候要看具體情況能否使用weak笤昨,可能值并不是所需要的值祖驱。
    4.使用Tagged Pointer
    Tagged Pointer是蘋果在64位系統(tǒng)引入的內(nèi)存技術(shù)。簡單來說就是對于NSString(內(nèi)存小于60位的字符串)或NSNumber(小于2^31)瞒窒,64位的指針有8個字節(jié)捺僻,完全可以直接用這個空間來直接表示值,這樣的話其實會將NSString和NSNumber對象由一個指針轉(zhuǎn)換成一個值類型,而值類型的setter和getter又是原子的匕坯,從而線程安全束昵。
    比如上述代碼的字符串改短一些,就不會崩潰了葛峻。
    從而我們可以總結(jié)到锹雏,線程安全有以下幾種方法:
    單線程串行訪問

訪問加鎖

使用不進行額外操作的關(guān)鍵字(weak)

使用值類型

然而這只是保證了基本的線程安全(不崩潰),若是需要保證訪問出符合預(yù)期的數(shù)據(jù)术奖,則需要采用GCD的barrier或者自己在合適的時機加鎖礁遵。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市采记,隨后出現(xiàn)的幾起案子佣耐,更是在濱河造成了極大的恐慌,老刑警劉巖唧龄,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兼砖,死亡現(xiàn)場離奇詭異,居然都是意外死亡既棺,警方通過查閱死者的電腦和手機讽挟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丸冕,“玉大人耽梅,你說我怎么就攤上這事∨种颍” “怎么了褐墅?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長洪己。 經(jīng)常有香客問我,道長竟贯,這世上最難降的妖魔是什么答捕? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮屑那,結(jié)果婚禮上拱镐,老公的妹妹穿的比我還像新娘。我一直安慰自己持际,他們只是感情好沃琅,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜘欲,像睡著了一般益眉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天郭脂,我揣著相機與錄音年碘,去河邊找鬼。 笑死展鸡,一個胖子當(dāng)著我的面吹牛屿衅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播莹弊,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼涤久,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了忍弛?” 一聲冷哼從身側(cè)響起响迂,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎剧罩,沒想到半個月后栓拜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡惠昔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年幕与,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镇防。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡啦鸣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出来氧,到底是詐尸還是另有隱情诫给,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布啦扬,位于F島的核電站中狂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏扑毡。R本人自食惡果不足惜胃榕,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瞄摊。 院中可真熱鬧勋又,春花似錦、人聲如沸换帜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惯驼。三九已至蹲嚣,卻和暖如春递瑰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背端铛。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工泣矛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人禾蚕。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓您朽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親换淆。 傳聞我的和親對象是個殘疾皇子哗总,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

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

  • ———————————————回答好下面的足夠了---------------------------------...
    恒愛DE問候閱讀 1,717評論 0 4
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,140評論 30 470
  • 史上最全的iOS面試題及答案 iOS面試小貼士———————————————回答好下面的足夠了----------...
    Style_偉閱讀 2,354評論 0 35
  • 多線程、特別是NSOperation 和 GCD 的內(nèi)部原理倍试。運行時機制的原理和運用場景讯屈。SDWebImage的原...
    LZM輪回閱讀 2,007評論 0 12
  • 生活就像海邊的海礁石與海水撞擊過無數(shù)次,雖然疼痛卻還是義無反顧县习。 我身邊有很多人涮母,形形色色的人,但又因為我的性格 ...
    瘋姑娘阿閱讀 210評論 2 2