I wrote the Objective-C code first
NSMutableString *aStrValue = [NSMutableString stringWithString:@"Hello"];
NSMutableDictionary *aMutDict = [NSMutableDictionary dictionary];
[aMutDict setObject:aStrValue forKey:@"name"];
NSLog(@"Before %@",aMutDict);
[aStrValue appendString:@" World"];
NSLog(@"After %@",aMutDict);
I got the output as follows
2015-09-17 14:27:21.052 ShareIt[4946:129853] Before {
name = Hello;
}
2015-09-17 14:27:21.057 ShareIt[4946:129853] After {
name = "Hello World";
}
Means when I append a string to a Mutable string which is actually referred into a MutableDictionary, the change is getting reflected in Dictionary too..
But then I tried something same in Swift
var stringValue:String?
stringValue = "Hello"
var dict:Dictionary = ["name":stringValue!]
println(dict)
stringValue! += " World"
stringValue!.extend(" !!!!")
println(dict)
I seen the output in playground like this
![](https://www.manongdao.com/static/images/pcload.jpg)
My Questions are
- Why the value that changed is not reflecting in a data structure like
Dictionary.
- Does in Swift adding any key value really keeps the value or its
reference, if it's keeping the reference like objective-C then here what is my mistake?
Reference type
The different behaviours depends on the fact that in the Objective-C code you use NSMutableString
that is a class
.
This means that aMutDict
and aStrValue
are references to the same object of type NSMutableString
. So the changes you apply using aStrValue
are visibile by aMutDict
.
Value type
On the other hand in Swift you are using the String
struct
. This is a value type. This means that when you copy the value from one variable to another, the change you do using the first variable are not visible to the second one.
The following example clearly describes the value type
behaviour:
var word0 = "Hello"
var word1 = word0
word0 += " world" // this will NOT impact word1
word0 // "Hello world"
word1 // "Hello"
Hope this helps.
Strings in Swift (copy by value) are completely different than string in Objective C (copy by reference).
From Apple' Swift documentation:
Strings Are Value Types
Swift’s String type is a value type. If you create a new String value,
that String value is copied when it is passed to a function or method,
or when it is assigned to a constant or variable. In each case, a new
copy of the existing String value is created, and the new copy is
passed or assigned, not the original version. Value types are
described in Structures and Enumerations Are Value Types.
Swift’s copy-by-default String behavior ensures that when a function
or method passes you a String value, it is clear that you own that
exact String value, regardless of where it came from. You can be
confident that the string you are passed will not be modified unless
you modify it yourself.
Behind the scenes, Swift’s compiler optimizes string usage so that
actual copying takes place only when absolutely necessary. This means
you always get great performance when working with strings as value
types.
In swift, String is a Struct.
Structs are not reference types in Swift, thus it's copied when you setting it to a dictionary.