2011-03-13 13 views
1

我有一個setter用於我想要輸入按照設置進行排序的類(它被稱爲不夠頻繁的成本是可以的),並且我想讓它快一點我想創建一個靜態的NSSortDescriptor來使用因爲排序參數總是相同的。NSSortDescriptor線程安全嗎?

setter的意思是原子,但我想知道是否可以在@synchronized塊之外的多個線程之間使用同一個NSSortDescriptor實例是安全的(因爲我在進入之前對輸入數組進行排序@synchronzied塊)。以下代碼線程安全嗎?或者這是否過早優化?

- (void) setMyArray:(NSArray*)newMyArray 
{ 
    static NSArray *sorter = nil; 

    @synchronized(self) 
    { 
     if (sorter == nil) 
     { 
     NSSortDescriptor *sortObj = [NSSortDescriptor sortDescriptorWithKey:@"size" ascending:YES]; 
     sorter = [[NSArray arrayWithObject:sortObj] retain]; 
     } 
    } 

    NSArray *sorted = [myNewArray sortedArrayUsingDescriptors:sorter]; 

    @synchronized(self) 
    { 
     // set iVar from sorted array... 
    } 
} 

回答

0

documentation specifically狀態:

不可變對象通常是 線程安全的;一旦你創建它們,你可以安全地將這些對象從線程傳遞給 。當然,當使用 不可變的對象時,您仍然需要 記得正確使用引用計數 。如果您不適當地釋放了一個您未保留的對象,則可能會在稍後導致異常。

由於如hoha觀察,NSSortDescriptor是不可變的,它是線程安全除非(類文檔中通常)特別指出,否則

+0

我知道不可變對象是線程安全的,但正如你在下面的迴應中指出的那樣,認爲某些東西是不可變的,因爲它看起來是不可變的,而且文檔沒有說它是不可改變的。在這種情況下,我還會在文檔上提出一個錯誤,以便向前推進。 – 2011-03-14 15:07:43

+0

謝謝。應該明確地明確說明! – bbum 2011-03-14 20:44:33

+0

歸檔雷達,bug ID 9131037。 – 2011-03-14 20:55:41

0

NSSortDescriptor沒有任何可見的方法來改變它,它沒有任何理由在內部改變其狀態,所以它是最有可能是線程安全的(除非蘋果做框架的代碼就可以破解它我懷疑)。

至於優化,它是(幾乎)總是過早的沒有實際的分析。在這種情況下,儘管我會用靜態變量來做同樣的事情 - 主要是爲了讓我的排序策略明確地被聲明/定義。

+0

當他們沒有這方面的文檔時,盲目地假設事情是線程安全的這通常是一個壞主意。您無法知道它是在內部操縱緩存還是進行任何其他形式的修改。 – 2011-03-13 19:52:20

+1

永遠不會*認爲任何東西都是線程安全的。如果某些內容是線程安全的,**將明確記錄爲**。做出這樣的假設*會導致崩潰*(並且通常會在軟件更新後導致崩潰)。 – bbum 2011-03-13 20:06:36

+0

@凱文巴拉德:是的,我沒有。我無法想象排序描述符中有任何可變狀態,但我無法證明它的不存在。這就是爲什麼我說 - 「最可能」。順便說一句,「線程編程指南」指出「不可變對象通常是線程安全的」,這對我來說是間接的證據。 – hoha 2011-03-13 20:12:43