2012-03-01 85 views
3

我試圖通過使用unlockWithCondition(使用NSConditionLock)來繞過NSLock,但無論我得到相同的結果:iOS SDK - NSLock消息:「從未鎖定的線程解鎖」

*斷開_NSLockError()進行調試。 * - [NSLock unlock]:lock('(null)')從未鎖定的線程解鎖。

我不確定是否it's不好,但什麼I'm這樣做是這樣的:

new Thread: 
[lockA lock];//waiting unlock 
[lockB lock];//waiting unlock 
..shared code.. 
[lockA unlock]; 
[lockB unlock]; 

in Main Thread: 
//Do two HTTP request. 

//when request respond, I unlock the locks in respective threads with [lockA unlock]; 
[lockB unlock]; 

所以部分 「..shared代碼..」 可以執行。我不明白爲什麼我會得到這個錯誤。

任何人都可以解釋我做錯了什麼?它看起來應該是完美的。

+0

有來自洛卡/ B在另一個線程調用? – 2012-03-01 16:56:08

+2

如果你在'_NSLockError()'上放置了一個斷點,它會給你一個堆棧跟蹤,顯示出現非法解鎖的位置。你嘗試過嗎? – user1118321 2012-03-01 18:31:36

+0

是的,我解析了請求在新線程上的響應。 – ZiggyST 2012-03-01 20:44:29

回答

6

我想你想在這裏使用鎖作爲信號量。鎖意味着阻止後臺線程和主線程同時訪問某些內容。因此,持有鎖的線程也必須釋放(解鎖)它。

如果您希望後臺線程等待主線程發生某些事情,請使用信號量。

使用GCD信號燈爲好,易於信號燈:https://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

+1

是的,謝謝,我不知道ios是否有信號量,這就是爲什麼我使用nslock。 – ZiggyST 2012-03-06 14:45:10

+0

如果這個答案實際上擴展了上述場景對信號量的使用,那將是非常好的... – 2016-02-17 14:13:17

1

如果你在NSURLConnection或類似的地方做你的HTTP請求,並試圖在委託中解鎖,你需要小心你創建和啓動NSURLConnection的位置,因爲它應該返回到該線程,除非你明確使用scheduleInRunLoop:mode把它放在另一個線程或運行循環中。

如果您確定您正在鎖定主線程,則應該在該線程上解鎖。在...空間

dispatch_async(dispatch_get_main_queue(), ^(void) { 
     ... 
    }); 

與您解鎖:回到那裏,你可以使用performSelectorOnMainThread:withObject:waitUntilDone:回調或GCD回調使用主線程。如果您在繼續之前需要知道解鎖已完成,則可以使用dispatch_sync()

但是,使用NSConditionLock,正如您所表示的那樣,您已經嘗試瞭解決方案。但是,您仍然需要在取回線程上執行鎖定,而不是在主線程上執行鎖定。該條件將由您的-unlockWithCondition:使用特定條件進行保護,因此在取回線程將其標記爲準備好之前它不會解鎖。

因此,在您的主線程中啓動檢索線程。在每個檢索線程中,-lock然後繼續檢索數據,然後-unlockWithContidition:。在消費者線程中,使用-lockWhenCondition,你應該沒問題。

不過,關鍵是你必須在同一個線程上鎖定和解鎖。

+0

非常感謝您的回答,我不是在同一個線程中解鎖,爲什麼這是一個問題?這是鎖的常用功能。,請等待其他人準備好 – ZiggyST 2012-03-01 20:43:39

+0

好吧,看到您已經嘗試過NSCondition鎖,我在上面添加了關於如何這樣做的註釋,而沒有遇到該錯誤。 – gaige 2012-03-03 16:24:10

+0

感謝您的回答,但我無法將它從解鎖它的線程中鎖定。我做什麼:我需要來自不同的HHTP請求的兩個不同的值,所以請求,並鎖定需要兩個值的函數(在另一個線程中使用performSelectorInBackground :),然後當請求響應,我解析他們在不同的線程,並當他們完成解析,我解鎖NSlock,所以另一個線程可以繼續使用這些值。 PD:使用NSconditionLock,我有相同的錯誤信息。 – ZiggyST 2012-03-05 15:24:00