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

Mar*_*cin 15 objective-c nsarray nscopying ios

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

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

    (...)
}
Run Code Online (Sandbox Code Playgroud)

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

[[NSArray alloc] initWithArray:myArray copyItems:YES]];
Run Code Online (Sandbox Code Playgroud)

bbu*_*bum 25

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

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

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

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

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

事实证明这是行不通的.如果区域中对象的单个引用泄漏出区域,那么一旦文档关闭,您的应用程序就会进入BOOM,并且对象无法告诉任何指向它的内容.其次,这个模型也成为GC'd系统中经常遇到的"稀缺资源"问题的牺牲品.也就是说,如果文档的对象图保持在非内存资源上,则在区域破坏之前无法有效地清理所述资源.

最后,将所有增加的脆弱性与一个糟糕的想法相结合,表现不太好(你经常关闭复杂文档的频率).但是,改变API的时间太晚了,我们留下了遗迹.

  • 如果有这样的问题你想引起我的注意,请在Twitter上随便给我@bbum.语言(和操作系统)的演变非常吸引人.如果它被记录下来,那么在狂想曲日期间它可能是一个遗留物.我认为在适当的Mac OS X版本中不推荐使用区域. (3认同)