2009-10-17 67 views
1

我應該在應用程序委託中製作一個NSLock實例,供所有類使用嗎?或者建議每個類根據需要實例化自己的NSLock實例?應該是一個NSLock實例「全球」?

如果我在第二種情況下鎖定工作,例如,是否可以訪問分佈在兩個視圖控制器上的託管對象上下文?

+0

使用手工編碼的鎖時非常害怕,並且懷疑對它們的需求。 – 2009-10-18 10:41:42

+2

我不確定這是什麼意思。如果使用線程,核心數據指南建議鎖定對託管對象上下文的訪問。除了手動編碼的'NSLock'鎖定 - 解鎖對之外,我還會使用什麼? – 2009-10-18 10:54:29

+0

是的,我只是說,小心......在這種情況下,這是適當的。 – 2009-10-18 20:57:12

回答

3

如果多個對象只訪問您的對象來讀取其內容,那麼您根本不需要鎖。如果至少有一個對象訪問您的對象以寫入/更新其內容,則其他對象是否訪問您的對象來讀取或寫入/更新對象並不重要:在這種情況下,您需要鎖定。

現在,爲了正確地保護您的對象(在多個對象可以訪問它的代碼的關鍵部分),您必須使用SAME LOCK INSTANCE,然後必須由所有訪問該對象的可能對象共享願意保護。

如果您的應用程序需要保護可能被大多數類同時訪問的對象,那麼擁有單個鎖實例就沒有問題。如果你想要更好的表現(尤其是如果你的對象同時訪問的數量很高),那麼你可以有多個鎖。每個鎖將負責允許/拒絕訪問對象的特定屬性/字段。這樣,幾個對象可以同時訪問您的對象來更改不同的屬性/字段。你基本上增加了你的對象的併發操作的數量。但是,每個鎖都必須在將訪問您保護的對象的其他對象之間共享。

每個控制器都有一個鎖定實例根本不起作用;這不會保護您的對象免受來自不同線程中其他對象的併發訪問。 NSLock是使用POSIX pthread互斥體實現的,因此它必須以完全相同的方式使用。這在NSLock文檔中也有明確說明:

警告:NSLock類使用POSIX線程來實現其鎖定行爲。向NSLock對象發送解鎖消息時,必須確保該消息是從發送初始鎖定消息的同一線程發送的。解鎖來自不同線程的鎖可能導致未定義的行爲。

因此,爲了保留臨界區語義,它是獲取負責完成釋放它的鎖的同一個線程。還要注意的是,鎖定機構僅用於快速操作,即在釋放它之前您應該只在很短的時間內獲得鎖定。如果您需要等待不可預知的時間,那麼您需要一個不同的同步機制,即通過NSCondition類可用的條件變量。

希望這會有所幫助。

+1

從文檔中明顯可以看出,用於鎖定特定線程的同一個鎖也可用於解鎖。然而,從'NSLock'的文檔中並不清楚所有類都必須使用同一個鎖實例。我也在閱讀,如果我多次使用'[myLock lock]',在發出相應的[[myLock unlock]]之前,該線程將凍結。所以我仍然不確定是否需要將'myLock'的實例化和範圍限制到被調用的特定類/線程,或者我是否可以毫無問題地使用應用程序範圍的'myLock'。 – 2009-10-18 10:52:39

+0

我建議閱讀posix pthread mutexes的文檔。你會看到一個互斥鎖(一個NSLock)必須在所有訪問你要保護的對象的線程之間共享。請注意,我並不是說它必須在所有線程中全局共享,只有這些線程才能訪問您的對象。你說連續兩次鎖定是正確的:除非互斥量遞歸,否則會出現問題。要使用遞歸互斥鎖,你必須使用一個NSRecursiveLock對象。請參閱「線程編程指南」文檔,特別是「同步」部分。 – 2009-10-18 18:57:11

1

您不應該對核心數據使用鎖。該文檔可能已過時。理想情況下,每個線程應該有一個上下文,並讓上下文處理其基礎NSPersistentStoreCoordinator的鎖定。這被認爲是當前在多線程應用程序中使用核心數據的安全方式。

相關問題