I've got a following problem.
I have a function called A which takes a following dictionary as an argument [String : MyClass]
, where MyClass is a custom class that I've created (it's a subclass of NSObject
).
MyClass has a property called firstProperty.
Function A looks like so:
func A (someDictionary : [String : MyClass]) {
var someDictionaryCopy = someDictionary
someDictionaryCopy["Key"].updateValue()
}
Ok, so the first line in the body of the function A is copying the someDictionary that is passed to the function A. But I DON'T want to mutate or modify the original someDictionary.
The second line: I take some existing value in the dictionary and run a method on MyClass instance which modifies one of its properties.
The thing is that if I run the code above, the original dictionary that's passed to the function is modified as well? Why is it so? How can I pass a dictionary to the function so that it's not mutated?
For your convenience, here's a sample of MyClass implementation:
class MyClass : NSObject {
var someProperty : Double = 0.0
func updateValue() {
someProperty += 10.0
}
}
The issue is that MyClass
is a reference type. When you copy the dictionary, it does, truly, make a new copy of the dictionary, but the new copy has references to the same instances of MyClass
that the original dictionary has. Changes made to a copy of a reference to an instance of MyClass
anywhere, whether it is inside a dictionary or any other value type, will be reflected in any other reference to that same instance of MyClass
.
Basically, the dictionary is a value type, which means it has value semantics. But the values in the dictionary are reference types, so they have reference semantics. The only way around this is to create a dictionary with new instances of MyClass
for every key in the dictionary. Or, as @EricD suggested, use structs instead of classes to get the value semantics that you want.