接觸開發(fā)稍微深一點的人都應該知道鎖的概念庶近,所謂鎖,就是在操作數(shù)據(jù)的時候霎槐,為了防止多個操作同時操作一個數(shù)據(jù)導致數(shù)據(jù)的錯亂或者非即時而采用的一種規(guī)避手段监右。
尤其在使用多線程進行開發(fā)時,由于多個線程的操作可能會同時對某個數(shù)據(jù)進行操作潦牛,可能是讀也可能是寫眶掌,如果不加以處理,那么可能在一個線程讀的時候另一個線程去寫罢绽,讀的線程得到的數(shù)據(jù)就可能不是最新的數(shù)據(jù)畏线,或者兩個線程同時對數(shù)據(jù)進行修改,導致一些不可預知的錯亂良价。
這時候就應該加一道鎖寝殴,在A線程操作數(shù)據(jù)的時候,將數(shù)據(jù)給鎖住明垢,鎖住的意思也就是不允許其他線程來操作這個數(shù)據(jù)蚣常,想操作的都得進行等待,直到 A操作完了痊银,才將鎖給打開抵蚊,這時才允許其他線程排隊進行操作。
說到鎖溯革,還有個概念不得不說贞绳,那就是信號量,信號量是用來控制加鎖解鎖的致稀,比如說一個變量冈闭,為0表示當前無人操作,為1表示當前有人操作抖单,那么當一個線程要操作時萎攒,先看這個信號量是不是0遇八,是0就可以操作, 是1就得等待耍休,這事一種信號量的形式刃永,還有多種形式。
在iOS開發(fā)中多線程也是經(jīng)常用到的東西羊精,因此對于一些關鍵的代碼就有必要加鎖斯够。iOS 中加鎖有多種方式,比如:
- NSLock
- dispatch_semaphore_wait
- @synchronized
本文要說的就是最后一種 @synchronized 的用法园匹。其實 @synchronized 用法很簡單雳刺,首先 @synchronized() 小括號內(nèi)需要一個參數(shù),這個參數(shù)就表示信號量裸违。這個參數(shù)可以是任何對象,包括 self本昏,或者是自定義的信號量供汛。針對不同的操作應該定義不同的信號量。
@synchronized() {...} 大括號中就是要加鎖執(zhí)行的代碼涌穆,代碼會操作一些數(shù)據(jù)怔昨。當開始執(zhí)行代碼時,意味著當前線程對其加鎖了宿稀,當代碼執(zhí)行完后趁舀,自動解鎖,其他線程才允許執(zhí)行此段代碼祝沸。
下面是用 self 作為信號量來加鎖的示例矮烹,也就是在當前實例中對此代碼塊操作要加鎖:
-(void)importantMethod
{
@synchronized(self)
{
// 關鍵代碼;
}
}
下面是使用自定義的信號量來加鎖的示例:
-(void)importantMethod
{
Account *account = [AccountaccoutFromString :[accountFiled stringValue]];
//獲取信號量
id accountSemaphore = [account semaphore];
@synchronized(accountSemaphore)
{
//關鍵代碼
}
}
值得一提的是這個加鎖機制是支持遞歸的,如果加鎖的代碼在當前線程中遞歸調(diào)用自身罩锐,那么會持續(xù)保持加鎖狀態(tài)奉狈,其余線程還是訪問不了,只有當遞歸完成全部執(zhí)行完后涩惑,或者出錯報異常退出后仁期,鎖才會解開,釋放信號量竭恬,其余線程才允許操作此段代碼塊跛蛋。