这可能是一个简单的问题,但是为什么在我的类(class)中实现NSCopying协议(protocol),却得到 zone == nil

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

    (...)
}

使用此方法对带有对象的复制数组进行调用。
[[NSArray alloc] initWithArray:myArray copyItems:YES]];

最佳答案

凯文和罗宾的答案是最准确的。奥斯卡的答案几乎是正确的。但是,无论是Gnustep文档还是logancautrell关于存在区域的原因都不是很正确的。

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

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

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

因此,如果文档的所有对象都是从单个区域分配的,并且该区域的分配元数据也位于该区域中,那么销毁与文档相关的所有对象的费用将与简单销毁该区域一样便宜(这实际上是便宜-“在这里,系统,将这些页面退回”-一个函数调用)。

事实证明这是行不通的。如果对区域中某个对象的单个引用泄漏出该区域,那么在关闭文档后,您的应用程序将变为 BOOM ,并且该对象无法告诉正在引用该对象的任何对象停止。其次,该模型还成为GC系统中经常遇到的“稀缺资源”问题的牺牲品。也就是说,如果文档的对象图保存在非内存资源上,则无法在区域破坏之前有效地清理所述资源。

最后,将性能提升(几乎多久才真正关闭复杂文档)与所有增加的脆弱性相结合的不足,使区域成为一个坏主意。不过,现在更改API太晚了,剩下的就是遗迹。

10-08 09:35