NSMutableDictionary setValue: forKeyPath: установка более одного ключа

// populate 'project' with contents of key in `gDictRoot`
NSDictionary *project = [gDictRoot valueForKeyPath:@"root.project0"];

// modify 'project' as necessary - actual code omitted for brevity
[project setValue:[someDict valueForKey:@"foo"] forKeyPath:@"parameters.foo"];

// add 'project' to 'gDictRoot' so it isn't lost when the view is dismissed
[gDictRoot setValue:project forKeyPath:@"root.project2"];

Третья строка, где я добавляю project к gDictRootproject0 также изменяется. Не знаю почему.


person Thromordyn    schedule 13.08.2012    source источник
comment
Что вам дает NSLog(@"%p %p", [gDictRoot valueForKeyPath:@"root.project0"], [gDictRoot valueForKeyPath:@"root.project2"]);?   -  person ldiqual    schedule 13.08.2012
comment
0x6b9cc10 0x6b9cc10 ... Я так понимаю, я неправильно инициализирую project?   -  person Thromordyn    schedule 13.08.2012
comment
Вы инициализируете его как указатель на то же самое, что и @"root.project0" в корневом словаре. Может быть, вы хотели копию?   -  person Phillip Mills    schedule 13.08.2012
comment
Только что получил 0x6b3eb30 0x6b27d90, так что это должно быть исправлено, но gDictRoot все еще сохраняет project как в root.project0, так и в root.project2.   -  person Thromordyn    schedule 13.08.2012


Ответы (1)


Поведение, которое вы видите, связано с тем, что и project0, и project2 указывают на один и тот же экземпляр словаря. Изменение в одном из них всегда будет отражаться в другом.

Если вы не хотите такого поведения, сделайте копию project0 перед созданием project2:

NSMutableDictionary *project = [NSMutableDictionary
    dictionaryWithDictionary:[gDictRoot valueForKeyPath:@"root.project0"]
];
person Sergey Kalinichenko    schedule 13.08.2012
comment
Думал, сработало. Не так много. - person Thromordyn; 13.08.2012
comment
@Thromordyn Это скопирует объекты первого уровня, но ссылки на объекты второго, третьего и более высокого уровня останутся прежними. Если вам нужно более глубокое клонирование, взгляните на этот вопрос и ответить. - person Sergey Kalinichenko; 13.08.2012
comment
Я понимаю. Приходится снова зацикливаться. Это или чтение из plist, так как это то, что я в конечном итоге все равно сделаю. Спасибо за помощь. - person Thromordyn; 13.08.2012