2011-12-28 3 views

ответ

7

Если вы не возражаете против количества времени, необходимого для крупного объекта, и вы на самом деле хотите глубоких копий объектов, вы можете сериализовать граф объекта и затем десериализовать его. Самый простой способ сделать это (при условии, что все ваши объекты являются объектами 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; 
} 
+0

К сожалению, это не работает, когда входной массив содержит NSNull – Vytis

2

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

1

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

NSArray *mutableArray = [originalArray mutableCopy]; 

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

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

+2

Я думаю, что если вы используете блок итератора, было бы более эффективным, так как вы бы прошли индекс и не должны искать его для каждого объекта , –

+0

О, я! Перечисление на основе блоков. Доступно на устройствах iOS 4+ рядом с вами сейчас! –

Смежные вопросы