2011-10-28 119 views
15

這可能是很簡單的問題,但爲什麼我班實施NSCopying協議,我得到區==零爲什麼zone在執行NSCopying時總是爲零?

- (id)copyWithZone:(NSZone *)zone 
{ 
    if (zone == nil) 
     NSLog(@"why this is allways nil"); 

    (...) 
} 

這是使用拷貝數組對象這個方法調用。

[[NSArray alloc] initWithArray:myArray copyItems:YES]]; 

回答

25

凱文和羅賓的答案是最準確的。奧斯卡的回答非常接近正確。但是,Gnustep文檔和logancautrell關於區域存在的原因都是非常正確的。

區域最初創建 - 首先是NXZone,然後是NSZone - 確保從單個區域分配的對象在內存中相對連續,這是事實。事實證明,這不會減少應用程序使用的內存量;在大多數情況下,它會略微增加它。

更大的目的是能夠大規模摧毀一組物體。

例如,如果要將複雜的文檔加載到基於文檔的應用程序中,那麼在文檔關閉時拆除對象圖實際上可能會非常昂貴。

因此,如果爲一個文件中的所有對象都從一個單一的區分配給該區域的分配的元數據是在該區域中,然後與文檔相關的所有對象的破壞將是作爲作爲廉價簡單地摧毀區域(這真的很便宜 - 「這裏,系統,這些頁面回來」 - 一個函數調用)。

這被證明是行不通的。如果對該區域中的某個對象的單個引用泄露出該區域,則在文檔關閉時應用程序將立即執行BOOM,並且該對象無法通知引用該對象停止的任何內容。其次,這種模式也成爲GC'd系統經常遇到的「稀缺資源」問題的犧牲品。也就是說,如果文檔的對象圖保存在非內存資源上,則在區破壞之前無法有效地清理所述資源。最後,一個表現勝利(通常你真的關閉複雜文檔的頻率)與所有附加脆弱性的結合使得區域成爲一個糟糕的主意。儘管如此,改變API的時間已經太晚了,我們仍然留下了痕跡。

+0

太棒了,我希望你能回答這個問題。注意,這是在任何時候在Apple文檔中記錄的?我今天可以找到的是NSZone *基礎方法。 – logancautrell

+3

如果有這樣的問題想要引起我的注意,請隨時關注@bbum我的Twitter。語言(和操作系統)的發展真的很吸引人。如果有記錄的話,它可能是在狂想曲日子裏剩下的。我認爲在適當的Mac OS X版本中不推薦使用區域。 – bbum

+1

我明白,你的帖子因爲你獨特的位置和歷史而被高度評價。我希望更多的蘋果工程師在這裏逗留! – logancautrell

1

區域是舊時代的遺留問題,當時計算機的RAM只有8MB或更少。

檢查了這一點(3.1.2內存分配和區域):

http://www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_3.html

還有該上從一個很好的討論可可製造商(以及它是可可開發郵件列表)大約10年前。這正是@ bbum所說的。

http://www.cocoabuilder.com/archive/cocoa/65056-what-an-nszone.html

顯然,這用在蘋果的文檔加以記錄,但在某些時候,因爲2007-06-06改變。

http://www.cocoadev.com/index.pl?NSZone

1

NSZone現在是一個無證類,因爲它是很老,它的目的是使用相同的設置虛擬內存頁面堆中分配的對象。然而,它大部分都不再使用,但由於它之前被使用過,所以該參數仍然存在,以便向後兼容。

3

NSZone很久以前就被棄用了。它仍然處於方法簽名(例如+allocWithZone:-copyWithZone:)的事實是爲了向後兼容。

+1

如果copyWithZone已被棄用(NSCopying協議定義中未提及),如何使用所需的copyWithZone實現NSCopying:在這些日子裏? – Marcin

+3

'-copyWithZone:'不被棄用。 'NSZone'是。只要忽略區域參數。 –

4

NULL區域意味着'使用默認區域'。現在的區域不再被現代的Objective C運行時所使用,並且根本不能用於ARC。

documentation

相關問題