2009-11-21 85 views
27

我有一段代碼,經常訪問並從主線程或幾個其他後臺線程。我需要確保一次只能處理一個代碼。@synchronized()和NSLock的區別

我目前使用@synchronized(self) { }塊,但我不確定這是否提供了正確的保護。它與NSLock實例有什麼不同?

最後,任何人都可以建議我如何保護我的方法?該方法是在我的應用程序委託,我通過調用訪問它從不同的線程:

[[[UIApplication sharedApplication] delegate] myMethod]; 

非常感謝,

邁克

回答

30

上有谷歌的Mac博客關於一個偉大的博客文章的@synchronized內部運作:
http://googlemac.blogspot.com/2006/10/synchronized-swimming.html

我目前使用 @synchro nized(self){} block,但我是 不知道這是否提供了 正確的保護。它與NSLock實例有什麼區別 ?

有幾種同步關鍵部分的方法(@synchronized, NSLock, OSSpinLock, ...)。
我認爲@synchronized是最方便的(and also the slowest)方法。
Here is a good SO answer解釋了@synchronized和NSLock之間的區別。

您正在通過共享實例(基本上是單例)委託訪問您的方法。也許你可以重新考慮你的設計,找出一種方法,讓你鎖定myMethod以內的一小段代碼。

+0

感謝您的幫助!總是使用'self'是否正確?在這種情況下,自我將指向應用程序委託,無論它是什麼調用它?我很困惑,爲什麼你必須傳遞一些東西到它! – 2009-11-21 21:15:26

+2

如果要鎖定「每個實例」和[YourClass類],並且要鎖定「每個類」,則使用(個人)。 (自我)意味着關鍵部分的執行需要爲當前(特定)對象同步。 – 2009-11-21 22:33:32

+0

啊,我明白了!非常感謝:-) – 2009-11-24 20:26:04

16

如果你確實有一些想要一次處理的項目,我的建議是使用NSOperations和一個NSOperationQueue,並將maxConcurrentOperationCount設置爲1.如果你確定唯一的方法是這個共享的代碼塊是通過這個隊列中的操作來訪問的,你將不再需要昂貴的鎖。

這可能需要對您的應用程序進行一些重組,但我發現在我自己的應用程序中應用此功能可以實現更好的性能和更簡潔的代碼。

+0

+1,但是人們應該認識到,「小重組」將要求你的代碼在本質上是完全異步的。 @synchronized意味着是一個同步阻塞鎖,而使用隊列將意味着調用站點不應該期望返回的值,而是使用塊回調來處理結果。這可能不適用於預計會阻止調用的代碼的關鍵部分。 – strangetimes 2017-04-17 11:20:40