为什么在实现 NSCopying 时 zone 总是为零?
这可能是一个简单的问题,但为什么在我的类中实现 NSCopying 协议,我得到 zone == nil
- (id)copyWithZone:(NSZone *)zone
{
if (zone == nil)
NSLog(@"why this is allways nil");
(...)
}
这被称为使用此方法复制带有对象的数组。
[[NSArray alloc] initWithArray:myArray copyItems:YES]];
It may be simple question, but why implementing NSCopying protocol in my class, I get zone == nil
- (id)copyWithZone:(NSZone *)zone
{
if (zone == nil)
NSLog(@"why this is allways nil");
(...)
}
This is called using this method for copy array with objects.
[[NSArray alloc] initWithArray:myArray copyItems:YES]];
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
凯文和罗宾的回答是最准确的。奥斯卡的回答非常接近正确。但无论是 Gnustep 文档还是 logancautrell 关于区域存在的理由都不太正确。
最初创建区域(首先是 NXZone,然后是 NSZone)是为了确保从单个区域分配的对象在内存中相对连续,这是事实。事实证明,这并没有减少应用程序使用的内存量;而是减少了应用程序使用的内存量。在大多数情况下,它最终会稍微增加。
更大的目的是能够大规模摧毁一组物体。
例如,如果要将复杂的文档加载到基于文档的应用程序中,则在关闭文档时拆除对象图实际上可能会非常昂贵。
因此,如果文档的所有对象都是从单个区域分配的,并且该区域的分配元数据也在该区域中,那么与该区域相关的所有对象都会被销毁。文档将像简单地破坏该区域一样便宜(这真的很便宜 - “这里,系统,让这些页面回来” - 一个函数调用)。
事实证明这是行不通的。如果对区域中某个对象的单个引用泄漏到区域之外,那么一旦文档关闭,您的应用程序就会BOOM,并且该对象无法分辨所引用的内容它停止。其次,这个模型也遇到了 GC 系统中经常遇到的“稀缺资源”问题。也就是说,如果文档的对象图占用非内存资源,则无法在区域破坏之前有效地清理所述资源。
最后,性能提升不够(您真正关闭复杂文档的频率)与所有增加的脆弱性相结合,使区域成为一个坏主意。然而,改变 API 已经太晚了,我们留下了痕迹。
Kevin's and Robin's answer is the most accurate. Oscar's answer is pretty close to correct. But neither the Gnustep documentation nor logancautrell's reasons for the existence of zones is quite correct.
Zones were originally created -- first NXZone, then NSZone -- to ensure that objects allocated from a single zone would be relatively contiguous in memory, that much is true. As it turns out, this does not reduce the amount of memory an app uses; it ends up increasing it slightly, in most cases.
The larger purpose was to be able to mass destroy a set of objects.
For example, if you were to load a complicated document into a document based application, tear-down of the object graph when the document was closed could actually be quite significantly expensive.
Thus, if all the objects for a document were allocated from a single zone and the allocation metadata for that zone was also in that zone, then destruction of all objects related to the document would be as cheap as simply destroying the zone (which was really cheap -- "here, system, have these pages back" -- one function call).
This proved unworkable. If a single reference to an object in the zone leaked out of the zone, then your app would go BOOM as soon as the document was closed and there was no way for the object to tell whatever was referring to it to stop. Secondly, this model also fell prey to the "scarce resource" problem so often encountered in GC'd system. That is, if the object graph of the document held onto non-memory resources, there was no way to clean up said resources efficiently prior to zone destruction.
In the end, the combination of not nearly enough of a performance win (how often do you really close complex documents) with all the added fragility made zones a bad idea. Too late to change the APIs, though, and we are left with the vestiges.
NULL 区域仅意味着“使用默认区域”。现代 Objective C 运行时不再使用区域,并且根本不能与 ARC 一起使用。
请参阅文档
A NULL zone just means 'use the default zone'. Zones aren't used by the modern Objective C runtime anymore and cannot be used with ARC at all.
See documentation
NSZone
很久以前就被弃用了。事实上,它仍然在方法签名中(例如+allocWithZone:
和-copyWithZone:
)是为了向后兼容。NSZone
was deprecated a long time ago. The fact that it's still in method signatures (e.g.+allocWithZone:
and-copyWithZone:
) are for backwards compatibility.NSZone 现在是一个未记录的类,因为它很旧,其目的是使用同一组虚拟内存页在堆上分配对象。然而,它大多不再使用,但由于之前使用过,所以该参数仍然存在,以实现向后兼容性。
NSZone
is now an undocumented class because it is quite old, its purpose was to allocate objects on the heap using the same set of virtual memory pages. However it is mostly not used anymore, but since it was used before, that parameter is still there for backwards compatibility.Zone 是旧时代的遗留物,当时计算机的 RAM 为 8 兆或更少。
查看此内容(3.1.2 内存分配和区域):
http: //www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_3.html
在 cocoa builder 上也对此进行了很好的讨论(好吧大约 10 年前就出现在 cocoa 开发者邮件列表中。这正是@bbum 所说的。
http://www.cocoabuilder.com/archive/cocoa/65056 -what-an-nszone.html
显然,这曾经记录在 Apple 文档中,但自 2007 年 6 月 6 日以来的某个时候发生了更改。
http://www.cocoadev.com/index.pl?NSZone
Zone is a legacy from the old days when computers had 8 megs or less of RAM.
Check this out (3.1.2 Memory Allocation and Zones):
http://www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_3.html
There is also a good discussion of this over on cocoa builder (well it was on the cocoa dev mailing list) from about 10 years ago. This is exactly what @bbum was saying.
http://www.cocoabuilder.com/archive/cocoa/65056-what-an-nszone.html
Apparently this used to be documented in the Apple docs, but it was changed at some point since 2007-06-06.
http://www.cocoadev.com/index.pl?NSZone