iOS中的多讀單寫問題

我們知道iOS中的數(shù)組和字典是線程不安全的。多線程編程中,當(dāng)多個線程對同一個字典dictionary進(jìn)行多讀單寫操作時,該如何來保證數(shù)據(jù)安全呢?
_ioQueue = dispatch_queue_create("ioQueue", DISPATCH_QUEUE_CONCURRENT);

(void)setSafeObject:(id)object forKey:(NSString *)key
{
key = [key copy];
dispatch_barrier_async(self.ioQueue, ^{
if (key && object) {
[_dic setObject:object forKey:key];
}
});
}
(id)getSafeObjectForKey:(NSString *)key
{
__block id result = nil;
dispatch_sync(self.ioQueue, ^{
result = [_dic objectForKey:key];
});
return result;
}
首先,我們需要創(chuàng)建一個私有的并行隊列來處理讀寫操作。
在這里不應(yīng)該使用globe_queue, 因為我們通過dispatch_barrier_async來保證寫操作的互斥,我們不希望寫操作阻塞住globe_queue中的其他不相關(guān)任務(wù),我們只希望在寫的同時,不會有其他的寫操作或者讀操作。
同時,也不推薦給隊列設(shè)置優(yōu)先級,多數(shù)情況下使用default就可以了。而改變優(yōu)先級往往會造成一些無法預(yù)料的問題,比如優(yōu)先級反轉(zhuǎn)(具體的可以參看參考文獻(xiàn))。
dispatch_barrier_async的block運(yùn)行時機(jī)是,在它之前所有的任務(wù)執(zhí)行完畢,并且在它后面的任務(wù)開始之前,期間不會有其他的任務(wù)執(zhí)行。注意在barrier執(zhí)行的時候,隊列本質(zhì)上如同一個串行隊列,其執(zhí)行完以后才會恢復(fù)到并行隊列。
另外一個值得注意的問題是,在寫操作的時候,我們使用dispatch_async,而在讀操作的時候我們使用dispatch_sync。很明顯,這2個操作一個是異步的,一個是同步的。我們不需要使每次程序執(zhí)行的時候都等待寫操作完成,所以寫操作異步執(zhí)行,但是我們需要同步的執(zhí)行讀操作來保證程序能夠立刻得到它想要的值。(寫操作是異步,不需要等待結(jié)果,直接返回;讀操作是同步,需要等待讀結(jié)果,是同步)。

使用sync的時候需要極其的小心,因為稍不注意,就有可能產(chǎn)生死鎖,這可能造成災(zāi)難性的后果。你肯定也注意到了在寫操作的時候?qū)ey進(jìn)行了copy, 關(guān)于此處的解釋,插入一段來自參考文獻(xiàn)的引用:

函數(shù)調(diào)用者可以自由傳遞一個NSMutableString的key,并且能夠在函數(shù)返回后修改它。因此我們必須對傳入的字符串使用copy操作以確保函數(shù)能夠正確地工作。如果傳入的字符串不是可變的(也就是正常的NSString類型),調(diào)用copy基本上是個空操作。

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

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

  • 我們知道iOS中的數(shù)組和字典是線程不安全的。多線程編程中,當(dāng)多個線程對同一個字典dictionary進(jìn)行多讀單寫操...
    王沐凡閱讀 3,055評論 2 11
  • 首先我們從一到線程安全的題目進(jìn)入 解決方案與原理 ARC版本 _ioQueue = dispatch_queue_...
    VincentHK閱讀 1,177評論 2 6
  • 未完,待更新 一、必備題 1、AFN 原理 鏈接:AFNetworking源碼——基本架構(gòu) - 簡書 2、SDWe...
    小熊_07cb閱讀 2,996評論 3 27
  • 設(shè)計模式是什么? 你知道哪些設(shè)計模式,并簡要敘述? 設(shè)計模式是一種編碼經(jīng)驗,就是用比較成熟的邏輯去處理某一種類型的...
    琦均煞Sylar閱讀 511評論 0 0
  • __block和__weak修飾符的區(qū)別其實是挺明顯的:1.__block不管是ARC還是MRC模式下都可以使用,...
    LZM輪回閱讀 3,583評論 0 6

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