Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do instance references really work in Swift?

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 enter image description here

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?
like image 488
Mrug Avatar asked Sep 17 '15 09:09

Mrug


People also ask

Is Swift value by reference?

In Swift there are two categories of types: value types and reference types. A value type instance keeps a unique copy of its data, for example, a struct or an enum . A reference type, shares a single copy of its data, and the type is usually a class .

Is array reference type in Swift?

In Objc string, array and dictionary are all reference types, while in Swift they are all value types.

Are tuples reference types Swift?

Types in Swift fall into one of two categories: first, “value types”, where each instance keeps a unique copy of its data, usually defined as a struct, enum, or tuple. The second, “reference types”, where instances share a single copy of the data, and the type is usually defined as a class.

Is function reference type in Swift?

In Swift, structs, enums and tuples are all value types, while classes and closures are reference types. In a nutshell, a value type contains data and a reference type contains the location in memory where data lives.


2 Answers

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.

like image 185
Luca Angeletti Avatar answered Sep 23 '22 20:09

Luca Angeletti


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.

like image 22
Abhinav Avatar answered Sep 22 '22 20:09

Abhinav