В чем разница между alloc и allocWithZone:? - PullRequest
50 голосов
/ 23 декабря 2010

Из обсуждения на форуме кажется, что большая разница заключается в коэффициенте производительности, allocWithZone: выделяет память из определенной области памяти, что снижает стоимость подкачки.

На практике почти нет шансов использовать allocWithZone: любой может привести простой пример, иллюстрирующий, в каком случае использовать allocWithZone:?

Спасибо

Ответы [ 6 ]

47 голосов
/ 23 декабря 2010

Когда один объект создает другой, это иногда хорошая идея, чтобы убедиться, они оба выделены из одного и того же область памяти. Зональный метод (объявлено в протоколе NSObject) может быть использован для этой цели; Это возвращает зону, в которой находится получатель расположен.

Это говорит о том, что ваши ивары и любые объекты, которые ваши классы "создают" сами, могут использовать +allocWithZone: таким образом, чтобы экземпляры, которые они создают, находились в одной зоне.

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

  return self;
}
30 голосов
/ 11 октября 2013

Из документации Apple :

Этот метод существует по историческим причинам; зоны памяти больше не используется Objective-C.

5 голосов
/ 18 ноября 2011

Хороший пример использования 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;

При копировании объекта сообщение «copy», которое вы отправляете, как указано выше (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 фактически используется.

2 голосов
/ 27 мая 2015

В справочнике по Foundation * все функции Zone теперь снабжены предупреждением о том, что зоны будут игнорироваться.

Зоны игнорируются в iOS и64-разрядная среда выполнения на OS X. Вы не должны использовать зоны в текущей разработке.

NSCreateZone
NSRecycleZone
NSSetZoneName
NSZoneCalloc
NSZoneFree
NSZoneFromPointer
NSZoneMalloc
NSZoneName
NSZoneRealloc
NSDefaultMallocZone
2 голосов
/ 05 октября 2012

Я использую allocWithZone в синглтоне. Как упоминал Форрест, создаваемые переменные выделяются из одной и той же области памяти. Таким образом, другие классы могут использовать или получать к ним доступ из той же зоны памяти. Экономьте место в памяти при запуске приложения.

0 голосов
/ 30 июля 2016

Даже если в документации Apple указано, что allocWithZone:

существует по историческим причинам; зоны памяти больше не используются Objective-C. Вы не должны переопределять этот метод.

и

Зоны игнорируются на iOS и 64-битной среде выполнения на OS X. Вы не должны использовать зоны в текущей разработке.

на самом деле я переопределил его в классе Objective C (в полном проекте Objective C), и метод вызывается, когда я делаю [[Mylass alloc] init], даже если сборка выполняется на iPhone 6s.

Но я думаю, что лучше следовать документации и переопределить метод alloc вместо этого, потому что alloc может выполнять ту же работу.

...