2016-05-04 2 views
0

У меня есть следующая проблема.Как предотвратить изменение копии словаря

У меня есть функция под названием , которая принимает следующий словарь в качестве аргумента [String : MyClass], где MyClass является пользовательским классом, который я создал (это подкласс NSObject). MyClass имеет свойство firstProperty.

Функция A выглядит так:

func A (someDictionary : [String : MyClass]) { 
    var someDictionaryCopy = someDictionary 

    someDictionaryCopy["Key"].updateValue() 
} 

Ok, так что первая линия в теле функции А копирует someDictionary, который передается функции А. Но я ДОН» T хочет изменить или изменить оригинальный someDictionary.

вторая строка: Я беру какое-то существующее значение в словаре и запускаю метод на экземпляре MyClass, который модифицирует одно из его свойств.

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

Для вашего удобства, вот пример реализации MyClass:

class MyClass : NSObject { 
    var someProperty : Double = 0.0 

    func updateValue() { 
     someProperty += 10.0 
    } 
} 
+4

Свифт-словари - это тип значения - оригинал * не * изменяется при обновлении копии. Это противоположность NSDictionary, который является * ссылочным * типом. Однако в вашем словаре Swift у вас есть * класс *: они являются ссылочным и будут обновляться из копии. – Moritz

+0

Итак, как мне скопировать словарь, чтобы значения внутри него не были изменены? – phbelov

+2

Вы не должны работать с классами, если вам не нужна эталонная работа, вместо этого используйте структуры. Но если вы используете классы, то обнимайте систему отсчета. Это мое предложение. :) – Moritz

ответ

3

Вопрос заключается в том, что MyClass является ссылочным типом. Когда вы копируете словарь, он действительно делает новую копию словаря, но новая копия имеет ссылки на те же экземпляры MyClass, что и в оригинальном словаре. Изменения, внесенные в копию ссылки на экземпляр MyClass в любом месте, будь то внутри словаря или любого другого типа значения, будут отражаться в любой другой ссылке на тот же экземпляр MyClass.

В принципе, словарь представляет собой тип значения, что означает, что он имеет семантику значений. Но значения в словаре являются ссылочными типами, поэтому они имеют ссылочную семантику. Единственный способ - создать словарь с новыми экземплярами MyClass для каждого ключа в словаре. Или, как предложил @EricD, используйте structs вместо классов для получения семантики значений, которые вы хотите.

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