51

论坛讨论来看,最大的区别似乎是性能因素,allocWithZone: 将从特定内存区域分配内存,从而降低交换成本。

在实践中,几乎没有机会使用 allocWithZone: ,任何人都可以举一个简单的例子来说明什么情况下使用 allocWithZone: ?

谢谢,

4

6 回答 6

47

当一个对象创建另一个对象时,有时最好确保它们都是从同一内存区域分配的。zone 方法(在 NSObject 协议中声明)可用于此目的;它返回接收器所在的区域。

这向我表明,您的 ivars 以及您的类“创建”自己的任何对象都可以通过+allocWithZone:这种方式使用,以在同一区域中创建它们创建的实例。

-(id)init {
  if (self = [super init]) {
    someIvar = [[SomeOtherClass allocWithZone:[self zone]] init];
  }

  return self;
}
于 2010-12-23T02:08:26.280 回答
30

来自苹果的文档

这种方法的存在是出于历史原因;Objective-C 不再使用内存区域。

于 2013-10-11T07:40:26.373 回答
5

使用 allocWithZone: 的一个很好的例子是当您实现 NSCopy 协议时,它允许您使您的自定义对象可复制(深度复制/按值复制),例如:

(1) ClassName *newObject = [currentObject copy]; //results in newObject being a copy of currentObject not just a reference to it

NSCopy 协议确保你实现一个方法:

(2) -(id)copyWithZone:(NSZone *)zone;

复制对象时,您发送的上述(1)“复制”消息在声明为“copyWithZone”时会向方法(2)发送消息。也就是你不需要做任何事情来获得一个区域。

现在,由于您向此消息发送了一个“区域”,因此您可以使用它来确保从与原始区域相同的内存中制作副本。

这可以像这样使用:

-(id)copyWithZone:(NSZone *)zone
{
   newCopy = [[[self class]allocWithZone:zone]init]; //gets the class of this object then allocates a new object close to this one and initialises it before returning
   return(newCopy);
}

这是我知道 allocWithZone 实际使用的唯一地方。

于 2011-11-18T13:44:27.147 回答
2

allocWithZone在单例中使用。正如 Forrest 所提到的,创建的变量是从同一内存区域分配的。因此,其他类可以从同一内存区域使用或访问它们。运行应用程序时节省内存空间。

于 2012-10-05T03:20:27.090 回答
2

Foundation Functions Reference中,所有Zone函数现在都带有以下警告,即区域将被忽略。

在 iOS 上忽略区域,在 OS X 上忽略 64 位运行时。您不应在当前开发中使用区域。

NSCreateZone
NSRecycleZone
NSSetZoneName
NSZoneCalloc
NSZoneFree
NSZoneFromPointer
NSZoneMalloc
NSZoneName
NSZoneRealloc
NSDefaultMallocZone
于 2015-05-27T20:53:42.417 回答
0

即使 Apple 的文档表明allocWithZone:

由于历史原因而存在;Objective-C 不再使用内存区域。您不应覆盖此方法。

在 iOS 上忽略区域,在 OS X 上忽略 64 位运行时。您不应在当前开发中使用区域。

实际上,我在一个 Objective-C 类(在一个完整的 Objective-C 项目中)中重写了它,[[Mylass alloc] init]即使构建在 iPhone 6s 上运行,当我这样做时也会调用该方法。

但我认为最好遵循文档和覆盖alloc方法而不是这个方法,因为 alloc 肯定可以做同样的工作。

于 2016-07-29T22:20:55.213 回答