为什么在实施NSCopying时区域总是为零?

时间:2011-10-28 19:52:28

标签: objective-c ios nsarray nscopying

这可能是一个简单的问题,但为什么在我的课堂上实施NSCopying协议,我得到 zone == nil

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

    (...)
}

对于带有对象的复制数组,使用此方法调用此方法。

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

5 个答案:

答案 0 :(得分:25)

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

最初创建了区域 - 首先是NXZone,然后是NSZone - 以确保从单个区域分配的对象在内存中相对连续,这是真的。事实证明,这并没有减少应用程序使用的内存量;在大多数情况下,它会稍微增加它。

更大的目的是能够大规模破坏一组物体。

例如,如果您要将复杂的文档加载到基于文档的应用程序中,那么在文档关闭时拆除对象图形实际上可能非常昂贵。

因此,如果文档的所有对象都是从单个区域分配的,则该区域的分配元数据在该区域中,然后销毁所有对象与文件相关的信息就像破坏区域一样便宜(这真的很便宜 - “这里,系统,让这些页面回来” - 一个函数调用)。

这被证明是行不通的。如果对区域中某个对象的单个引用泄漏出该区域,那么一旦文档关闭,您的应用就会 BOOM ,并且该对象无法告诉所指的任何内容它要停下来。其次,这个模型也成为GC'd系统中经常遇到的“稀缺资源”问题的牺牲品。也就是说,如果文档的对象图保存在非内存资源上,则在区域销毁之前无法有效地清理所述资源。

最后,将所有增加的脆弱性与一个不太好的性能胜利(你经常关闭复杂文档的频率)相结合是一个坏主意。但是,改变API的时间太晚了,我们留下了遗迹。

答案 1 :(得分:4)

NULL区域仅表示“使用默认区域”。现在的Objective C运行时不再使用区域,根本不能与ARC一起使用。

请参阅documentation

答案 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以来,它在某些时候发生了变化。

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

答案 4 :(得分:1)

NSZone现在是一个未记录的类,因为它很老,它的目的是使用同一组虚拟内存页面在堆上分配对象。但是它几乎不再使用,但由于之前使用过,该参数仍然存在向后兼容性。