2011-10-28 56 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

相关问题