Копирование коллекций

Cocoa

Есть два вида копирования объекта: неполное и полное. Нормальная копия - неполная копия, производящая новую коллекцию, которая разделяет собственность на объекты с оригиналом. Полная копия создать новые объекты из оригиналов и добавить их в новую коллекцию. Это различие иллюстрируется на рисунке 1.

Рисунок 1 Неполная и полная копии.

Cocoa copy collections

Неполные копии

Есть несколько способов сделать неполную копию коллекции. При создании неполную копии, объектам в оригинальной коллекции направляется сообщение retain и указатели копируются в новую коллекцию. Пример ниже, показывает некоторые способы создания новой коллекции, используя неполную копию.

NSArray *shallowCopyArray=[someArray copyWithZone:nil];

NSDictionary *shallowCopyDict=[[NSDictionary alloc] initWithDictionary:
    someDictionary copyItems: NO];

Эти методы не ограничиваются показанными коллекциями. Например, вы можете скопировать набор методами copyWithZone: или mutableCopyWithZone: или массив initWithArray:copyItems:.

Полные копии

Есть два способа сделать полные копии коллекций. Вы можете использовать эквивалентные коллекции из initWithArray:copyItems: с YES в качестве второго параметра. Если вы создадите полную копию коллекции таким образом, каждому объекту в коллекции передается сообщение copyWithZone:. Если объекты в коллекции принимают NSCopying протокол, объекты полностью копируются в новую коллекцию, которая затем единолично владеет копируемыми объектами. Если объекты не принимают NSCopying протокол, попытка скопировать их таким образом, приведет к ошибке выполнения. Тем не менее, copyWithZone: производит поверхностное копирование. Такое копирование способно производить только один уровень глубокого копирования. Если вам нужен только один уровень полной копии, вы можете явно вызвать инициализатор, как в листинге 2.

Листинг 2 Создание полной копии

NSArray *deepCopyArray=[[NSArray alloc] initWithArray: someArray copyItems: YES];

Эта техника также относится и к другим коллекциям. Используйте эквивалент коллекции из initWithArray:copyItems: с YES в качестве второго параметра.

Если вам необходимо истинно полное копирование, например, когда у вас есть массив массивов, вы можете архивировать и разархивировать коллекции при условии, что содержимое всех массивов соответствует NSCoding протоколу. Пример этого метода показан в листинге 3.

Листинг 3 истинно полное копирование

NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
          [NSKeyedArchiver archivedDataWithRootObject: oldArray]];

Копирование и изменчивость

При копировании коллекции, изменчивость данной коллекции и объекты в неq могут быть затронуты. Каждый метод копирования имеет несколько различных воздействий на изменчивость объектов в коллекции произвольной глубины:

  • copyWithZone: делает на уровне поверхностно неизменном. Все более глубокие уровни имеют изменчивость как ранее.
  • initWithArray:copyItems: с NO в качестве второго аргумента дает поверхностный уровень изменчивости выделяемого класса. Все более глубокие уровни имеют изменчивость как ранее.
  • initWithArray:copyItems: с YES в качестве второго параметра дает поверхностный уровень изменчивости выделяемого класса. Следующий уровень является неизменным, и все более глубокие уровни имеют изменчивость как ранее.
  • Архивирование и распаковка коллекции оставляет изменчивость на всех уровнях, какой она была раньше.
 
 
homeЗаметили ошибкукарта сайта 
   Made on a Mac