这可能是一个简单的问题,但为什么在我的课堂上实施NSCopying协议,我得到 zone == nil
- (id)copyWithZone:(NSZone *)zone
{
if (zone == nil)
NSLog(@"why this is allways nil");
(...)
}
对于带有对象的复制数组,使用此方法调用此方法。
[[NSArray alloc] initWithArray:myArray copyItems:YES]];
答案 0 :(得分:25)
凯文和罗宾的答案是最准确的。奥斯卡的答案非常接近正确。但是Gnustep文档和logancautrell存在区域的原因都不是正确的。
最初创建了区域 - 首先是NXZone,然后是NSZone - 以确保从单个区域分配的对象在内存中相对连续,这是真的。事实证明,这并没有减少应用程序使用的内存量;在大多数情况下,它会稍微增加它。
更大的目的是能够大规模破坏一组物体。
例如,如果您要将复杂的文档加载到基于文档的应用程序中,那么在文档关闭时拆除对象图形实际上可能非常昂贵。
因此,如果文档的所有对象都是从单个区域和分配的,则该区域的分配元数据也在该区域中,然后销毁所有对象与文件相关的信息就像破坏区域一样便宜(这真的很便宜 - “这里,系统,让这些页面回来” - 一个函数调用)。
这被证明是行不通的。如果对区域中某个对象的单个引用泄漏出该区域,那么一旦文档关闭,您的应用就会 BOOM ,并且该对象无法告诉所指的任何内容它要停下来。其次,这个模型也成为GC'd系统中经常遇到的“稀缺资源”问题的牺牲品。也就是说,如果文档的对象图保存在非内存资源上,则在区域销毁之前无法有效地清理所述资源。
最后,将所有增加的脆弱性与一个不太好的性能胜利(你经常关闭复杂文档的频率)相结合是一个坏主意。但是,改变API的时间太晚了,我们留下了遗迹。
答案 1 :(得分:4)
NULL区域仅表示“使用默认区域”。现在的Objective C运行时不再使用区域,根本不能与ARC一起使用。
答案 2 :(得分:3)
NSZone
很久以前就被弃用了。它仍处于方法签名(例如+allocWithZone:
和-copyWithZone:
)的事实是为了向后兼容。
答案 3 :(得分:1)
区域是计算机具有8兆或更少内存的旧时代的遗产。
检查出来(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
显然,这曾经在Apple文档中记录过,但自2007-06-06以来,它在某些时候发生了变化。
答案 4 :(得分:1)
NSZone
现在是一个未记录的类,因为它很老,它的目的是使用同一组虚拟内存页面在堆上分配对象。但是它几乎不再使用,但由于之前使用过,该参数仍然存在向后兼容性。