Делает ли mutableCopy содержащиеся объекты изменяемыми? - PullRequest
2 голосов
/ 29 декабря 2011

myArray - это NSArray объектов NSDictionary. Будет ли [myArray mutableCopy] содержать исходные объекты NSDictionary или копии NSMutableDictionary? Есть ли простой способ сделать неизменный граф объектов полностью изменяемым?

Ответы [ 3 ]

7 голосов
/ 29 декабря 2011

Если вы не возражаете против количества времени, необходимого для большого графа объектов, и вы на самом деле хотите получить глубокие копии объектов, вы можете сериализовать свой граф объектов и затем десериализовать его. Самый простой способ сделать это (при условии, что все ваши объекты являются объектами Foundation Collection) - это использовать класс NSPropertyListSerialization . Сериализуйте ваш корневой объект в данные, затем десериализуйте в изменяемый массив корневого уровня, используя опцию NSPropertyListMutableContainersAndLeaves. Полученный в результате изменяемый массив корневого уровня будет глубокой копией, а все контейнеры будут изменяемыми. Важно помнить, что это действительно будет глубокая копия, поэтому, если вы измените что-то в другом контейнере, это изменение не будет отражено в исходных объектах.

Вот краткий пример кода:

// Assumes the root-level object is an array, adjust as necessary
- (NSMutableArray*)deepMutableCopyOfArray:(NSArray*)array error:(NSError**)outError
{
  NSError* error = nil;
  NSData* serializedData = [NSPropertyListSerialization dataWithPropertyList:array format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error];
  if( !serializedData ) {
    if( outError ) *outError = error;
    return nil;
  }

  NSMutableArray* mutableCopy = [[NSPropertyListSerialization propertyListWithData:serializedData options:NSPropertyListMutableContainersAndLeaves format:NULL error:&error] retain];
  if( !mutableCopy ) {
    if( outError ) *outError = error;
    return nil;
  }

  return mutableCopy;
}
2 голосов
/ 29 декабря 2011

Копии в какао, как правило, мелкие.Это означает, что он влияет только на самый верхний объект, в данном случае на массив.Вы получите изменчивый массив неизменяемых словарей.Не существует одного вкладыша, который бы сделал все это изменчивым, как вы просите.

1 голос
/ 29 декабря 2011

Единственный способ сделать это - перебрать исходный массив, создать изменяемые копии каждого объекта и заменить неизменяемые объекты в изменяемом массиве их изменяемыми собратьями. Вот так, слово mutable потеряло всякий смысл.

NSArray *mutableArray = [originalArray mutableCopy];

for (NSDictionary *dictionary in originalArray)
{
    NSInteger index = [originalArray indexOfObject:dictionary];
    NSMutableDictionary *mutableDictionary = [dictionary mutableCopy];
    [mutableArray replaceObjectAtIndex:index withObject:mutableDictionary];
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...