为什么区域在执行NSCopying时总是为零?

这可能是一个简单的问题,但为什么在我的类中实现NSCopying协议,我得到了区域== nil

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

这被称为使用这种方法复制数组与对象。

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

凯文和罗宾的答案是最准确的。 奥斯卡的回答是非常接近正确的。 但Gnustep的文档和logancautrell的存在区域的原因都是非常正确的。

区域最初被创build – 首先是NXZone,然后是NSZone,以确保从单个区域分配的对象在内存中相对连续,这是事实。 事实certificate,这不会减less应用程序使用的内存量。 在大多数情况下,它会略微增加。

更大的目的是能够大规模地摧毁一组物体。

例如,如果您要将复杂的文档加载到基于文档的应用程序中,则在closures文档时拆除对象图实际上可能会相当昂贵。

因此,如果一个文档的所有对象都是从一个区域分配的, 并且该区域的分配元数据也在该区域中,那么销毁与该文档相关的所有对象将会像简单地破坏该区域一样便宜(这是真的便宜 – “在这里,系统,有这些网页” – 一个函数调用)。

这certificate是行不通的。 如果对区域中的某个对象的单个引用泄漏到区域之外,那么一旦文档closures,您的应用程序就会进入BOOM状态 ,并且对象无法告诉引用该对象的任何内容停止。 其次,这种模式也陷入了GC'd系统经常遇到的“稀缺资源”问题。 也就是说,如果文档的对象图保存在非内存资源上,则在区破坏之前无法有效地清理所述资源。

最后,一个performance不佳的组合(你真正closures复杂文档的频率如何)以及所有增加的脆弱性使得这些区域成为一个糟糕的主意。 但是,改变API的时间太晚了,我们留下了遗留问题。

NULL区域意味着“使用默认区域”。 现在的Objective C运行时不再使用区域,也不能使用ARC。

见文件

NSZone很久以前就被弃用了。 它仍然在方法签名(例如+allocWithZone:-copyWithZone:是为了向后兼容。

NSZone现在是一个未NSZone的类,因为它是相当古老的,其目的是使用同一组虚拟内存页面在堆上分配对象。 然而,它大部分都不再使用,但是由于之前使用过,所以这个参数仍然是为了向后兼容。

当计算机有8兆或更less的内存时,区域是过去的遗留问题。

检查出来(3.1.2内存分配和区域):

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

大约10年前,关于cocoa制造商(以及cocoa开发邮件列表)的讨论也很多。 这正是@bbum所说的。

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

显然这在苹果文档中有记载,但是自2007-06-06以来,这一点已经发生了变化。

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