2009-02-24 27 views
13

我想通過存儲在NSSet幾個對象執行相同的操作。可可的NSArray/NSSet中:-makeObjectsPerformSelector:對快速列舉

我第一次嘗試使用一個快速列舉:

for (id item in mySetOfObjects) 
    [item action]; 

它工作得很好。然後我想到:

[mySetOfObjects makeObjectsPerformSelector:@selector(action)]; 

而現在,我不知道什麼是最好的選擇。據我所知,這兩種解決方案是等價的。但是有沒有更喜歡一種解決方案的論點?

回答

21

我認爲使用makeObjectsPerformSelector,因爲它允許的NSSet對象照顧自己的索引,循環和消息收發。編寫NSSet代碼的人最有可能知道實現該特定循環的最佳方式。

在最壞的情況下,他們只會實現完全相同的循環,而您獲得的所有代碼都是稍微更乾淨的代碼(不需要包含循環)。充其量,他們做了一些內部優化,代碼實際上運行得更快。

的主題簡要蘋果Code Speed Performance文件標題爲「展開循環」一節中提到。

如果您關心性能,最好的辦法是設置一個快速程序,對一組中的對象執行一些選擇器。讓它運行數百萬次,並且計算兩種不同情況之間的差異。

+0

謝謝你的鏈接,我不知道這個文件!正如你所說,「展開循環」一節明確指出Cocoa開發者已經用-makeObjectsPerformSelector: – mouviciel 2009-02-24 19:53:11

2

makeObjectsPerformSelector:可能稍微快一點,但我懷疑有將是時間的任何實際差別99%。雖然它更簡潔明瞭,但我會因爲這個原因而使用它。

4

我不會用makeObjectsPerformSelector,原因很簡單,它是一種叫,你沒有看到所有的時候。這就是爲什麼例如 - 我需要添加調試代碼作爲枚舉數組,而你真的不能使用makeObjectsPerformSelector來做到這一點,除非你改變代碼如何在Release模式下工作,這是一個真正的否定。

for (id item in mySetOfObjects) 
{ 
    #if MY_DEBUG_BUILD 
    if ([item isAllMessedUp]) 
     NSLog(@"we found that wily bug that has been haunting us"); 
    #endif 

    [item action]; 
} 

--Tom

7

我也提交了這個問題。我發現在蘋果的文檔「類別編程主題」,「Sets: Unordered Collections of Objects」下的以下內容:

的NSSet中的方法objectEnumerator讓 您遍歷集合中的一個 接一個的元素。而 themakeObjectsPerformSelector:和 makeObjectsPerformSelector:withObject: 方法提供了在一組發送消息 單個對象。在 大多數情況下,快速枚舉應該使用 ,因爲它比使用NSEnumerator或 makeObjectsPerformSelector: 方法更靈活,更靈活 。有關枚舉的更多信息,請參見 「枚舉:遍歷一個 集合的元素。「

這使我相信快速枚舉仍然是此應用程序的最有效手段。

1

如果純粹的速度是唯一的問題(即你正在創建一個渲染引擎,每個微小的CPU週期計數),迭代通過任何NSCollection對象(從iOS 5.0到6.0)的最快方法是各種「enumerateObjectsUsingBlock」方法。我不知道這是爲什麼,但我測試了它,這似乎是這樣的...

我寫了小測試創建數以十萬計的對象的集合,每個對象都有一個方法,它將一個簡單的int數組。這些集合中的每一個都被迫執行各種類型的迭代(for循環,快速枚舉,makeObjectsPerformSelector和enumerateObjectsUsingBlock)數百萬次,並且在幾乎所有情況下,「enumerateObjectsUsingBlock」方法都在測試過程中輕鬆勝出。

唯一不是這樣的情況是,當內存開始填滿時(我開始用對象的百萬運行它),之後它開始失去「makeObjectsPerformSelector」。

對不起,我沒有拍攝代碼的快照,但這是一個非常簡單的測試,我強烈建議您嘗試一下,看看自己。 :)