Почему при реализации NSCopying зона всегда равна нулю? - PullRequest
15 голосов
/ 28 октября 2011

Это может быть простой вопрос, но почему при реализации протокола NSCopying в моем классе я получаю zone == nil

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

    (...)
}

Вызывается при использовании этого метода для копирования массива с объектами.

[[NSArray alloc] initWithArray:myArray copyItems:YES]];

Ответы [ 5 ]

25 голосов
/ 29 октября 2011

Ответ Кевина и Робина самый точный. Ответ Оскара довольно близок к правильному. Но ни документация Gnustep, ни причины существования зон не вполне верны.

Зоны были изначально созданы - сначала NXZone, затем NSZone - чтобы гарантировать, что объекты, выделенные из одной зоны, будут относительно смежными в памяти, что очень верно. Оказывается, это не уменьшает объем памяти, используемой приложением; в большинстве случаев оно немного увеличивается.

Большая цель состояла в том, чтобы иметь возможность массового уничтожения множества объектов.

Например, если вы загружаете сложный документ в приложение, основанное на документе, демонтирование графа объектов, когда документ закрыт, может на самом деле быть довольно значительно дорогим.

Таким образом, если все объекты для документа были выделены из одной зоны и , метаданные выделения для этой зоны были также в этой зоне, то уничтожение всех объектов, связанных с документ будет таким же дешевым, как просто уничтожение зоны (что было действительно дешево - «здесь, система, верните эти страницы» - один вызов функции).

Это оказалось неосуществимым. Если бы одна ссылка на объект в зоне просочилась из зоны, то ваше приложение отправлялось бы BOOM , как только документ был закрыт, и у объекта не было возможности сказать, что ссылается на него прекратить. Во-вторых, эта модель также стала жертвой проблемы «дефицитных ресурсов», так часто встречающейся в системе GC. То есть, если граф объектов в документе хранится в ресурсах, не связанных с памятью, не было никакого способа эффективно очистить упомянутые ресурсы перед уничтожением зоны.

В конце концов, сочетание недостаточного выигрыша в производительности (как часто вы действительно закрываете сложные документы) со всей добавленной хрупкостью сделали зоны плохой идеей. Однако уже слишком поздно менять API, и у нас остались остатки.

4 голосов
/ 28 октября 2011

Зона NULL просто означает «использовать зону по умолчанию». Зоны больше не используются современной средой выполнения Objective C и вообще не могут использоваться с ARC.

См. документацию

3 голосов
/ 28 октября 2011

NSZone устарела давно.Тот факт, что он все еще находится в сигнатурах методов (например, +allocWithZone: и -copyWithZone:), предназначен для обратной совместимости.

1 голос
/ 28 октября 2011

NSZone теперь недокументированный класс, потому что он довольно старый, его целью было выделение объектов в куче с использованием того же набора страниц виртуальной памяти.Однако в большинстве случаев он больше не используется, но поскольку он использовался ранее, этот параметр все еще существует для обратной совместимости.

1 голос
/ 28 октября 2011

Зона - это наследие прежних времен, когда на компьютерах было 8 или менее мегабайт ОЗУ.

Проверьте это (3.1.2 Распределение памяти и зоны):

http://www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_3.html

Существует также хорошее обсуждение этого вопроса по какао-сборщику (ну, это было в списке рассылки разработчиков какао) около 10 лет назад.Это именно то, о чем говорил @bbum.

http://www.cocoabuilder.com/archive/cocoa/65056-what-an-nszone.html

Очевидно, это было задокументировано в документации Apple, но в какой-то момент оно изменилось с 2007-06-06.

http://www.cocoadev.com/index.pl?NSZone

...