Вопрос о глубоком копировании - PullRequest
1 голос
/ 29 мая 2011

В книге «Начинающий iPhone 4» у автора есть этот код, чтобы создать категорию для создания глубокой копии NSDictionary, в котором есть NSArray имен для каждой буквы алфавита, чтобы показать пример индексированной таблицы с поискомbar.

#import "NSDictionary-MutableDeepCopy.h"
@implementation NSDictionary (MutableDeepCopy)
- (NSMutableDictionary *) mutableDeepCopy { 
    NSMutableDictionary *returnDict = [[NSMutableDictionary alloc] initWithCapacity:[self count]]; 
    NSArray *keys = [self allKeys]; 
    for (id key in keys) {
        id oneValue = [self valueForKey:key]; 
        id oneCopy = nil;
        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)]) oneCopy = [oneValue mutableDeepCopy];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)]) oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil) 
           oneCopy = [oneValue copy];
        [returnDict setValue:oneCopy forKey:key]; 
        [oneCopy release];
    } 
    return returnDict;
} 

@end

Может кто-нибудь объяснить логику цикла for?Я не уверен, что он пытается сделать, чтобы увидеть, какое значение отвечает на какой селектор и почему оно будет добавлено в словарь.Спасибо.

Ответы [ 2 ]

3 голосов
/ 29 мая 2011

Итак, цикл for просто перебирает все ключи в словаре.Предварительно мы создаем новый словарь с именем returnDict - это будет то, что мы возвращаем.

Для каждого ключа в словаре, который мы хотим скопировать, мы ...

  1. Получить объект, сохраненный для этого ключа ([self valueForKey:key]), и сохранить его в переменной с именем oneValue.

  2. Если oneValue реализует наш метод mutableDeepCopy (т.е., это NSDictionary) иди вызови его и присвои возвращаемое значение в переменную с именем oneCopy.

  3. Иначе, мы увидим, реализует ли oneCopy метод mutableCopy,Если это так, мы помещаем вывод в переменную oneCopy.

  4. На этом этапе мы проверяем, не выполняются ли следующие шаги (2) и (3) переменная oneCopyему было назначено что-либо (if (oneCopy == nil)).Если это не так (т. Е. Оно равно nil), мы можем предположить, что объект не реализует либо mutableDeepCopy, либо mutableCopy, поэтому мы вместо этого вызываем простой старый copy и присваиваем его значение oneCopy.

  5. Добавьте oneCopy в наш словарь returnDict, используя оригинальный ключ.

Это цикл for - в концевсе, мы идем и возвращаем скопированный словарь.

0 голосов
/ 30 мая 2011

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

  • Используйте mutableDeepCopy, если возможно (если объект понимает это сообщение).
  • В противном случае используйте mutableCopy, если это возможно.
  • Если ничего не помогает, просто используйте copy.

Если объект просто не копируемый, ваш код становится бумом при отправке объекта -copy, поскольку не проверяется, отвечает ли объект на -copy. Это уместно, поскольку попытка глубокого копирования массива, содержащего элементы, которые не могут быть скопированы, определенно является ошибкой программиста.

...