Value types vs Reference types in swift (basics)

ref – https://www.raywenderlich.com/112027/reference-value-types-in-swift-part-1

Value types keep a unique copy of their data, while reference types share a single copy of their data.

Reference type

Swift represents a reference type as a class. This is similar to Objective-C, where everything that inherits from NSObject is stored as a reference type.

In Objective-C — and most other object-oriented languages — you hold references to objects. In Swift, however, you use class which is implemented using reference semantics.

The above class represents a pet dog and whether or not the dog has been fed. Create a new instance of your Dog class by adding the following:

This simply points to a location in memory that stores dog. To add another object to hold a reference to the same dog, add the following:

Because dog is a reference to a memory address, puppy points to the exact same address. Feed your pet by setting wasFed to true:

value-reference-480x196

Therefore you’d expect any change in one to be reflected in the other. Check that this is true by viewing the property values in your playground:

Changing one named instance affects the other since they both reference the same object. This is exactly what you’d expect in Objective-C.

Value types

There are many kinds of value types in Swift, such as struct, enum, and tuples. You might not realize that Objective-C also uses value types in number literals like NSInteger or even C structures like CGPoint.

Clearly, a equals 42 and b equals 43. If you’d declared them as reference types instead, both a and b would equal 43 since both would point to the same memory address.

This shows a subtle, but important difference between reference and value types: setting kitty‘s wasFed property has no effect on cat. The kitty variable received a copy of the value of cat instead of a reference.

value-value-480x206

Although it’s much faster to assign a reference to a variable, copies are almost as cheap. Copy operations run in constant O(n) time since they use a fixed number of reference-counting operations based on the size of the data.

Mutability

For reference types, let means the reference must remain constant. However, you can still dereference them and change the data. In other words, you can’t change the instance the constant references, but you can mutate the instance itself.

For value types let means the instance must remain constant. No properties of the instance will ever change, regardless whether the property is declared with let or var.

It’s much easier to control mutability with value types. To achieve the same immutability/mutability behavior with reference types, you’d need to implement immutable and mutable class variants such as NSString and NSMutableString.

Which to Use and When

When to Use a Value Type

Generally speaking, use value types in the following instances:

Comparing instance data with == makes sense

“But of course,” you say. “I want every object to be comparable!”. But you need to consider whether the data should be comparable. Consider the following implementation of a point:

Does that mean two variables with the exact same x and y members should be considered equal?

It’s clear that these two Points with the same internal values should be considered equal. The memory location of those values doesn’t matter; you’re concerned about the values themselves.

Therefore, you’d need to conform to the Equatable protocol, which is good practice for all value types. This protocol defines only one function which you must implement globally in order to compare two instances of the object. This means that the == operator must have the following characteristics:

Reflexive: x == x is true
Symmetric: if x == y then y == x
Transitive: if x == y and y == z then x == z

If you have a custom struct, you’d implement the equal sign like so:

Copies should have independent state

Structs, being value types, have independent state.

Let’s instantiate two Shape structs.

If we are to change their state, it would be unique.

Each Shape needs its own copy of a Point so you can maintain their state independent of each other.

The data will be used in code across multiple threads

This one’s a little more complex. Will multiple threads access this data? If so, will it really matter if the data isn’t equal across all threads at all times?
To make your data accessible from multiple threads and equal across threads, you’ll need:

1) to use a reference type and
2) implement locking as well

Thus, if threads can uniquely own the data, using value types makes the whole point moot since each owner of the data holds a unique copy rather than a shared reference.

When to Use a Reference Type

Although value types are useful in many cases, reference types are still useful in the following situations:

Comparing instance identity with === makes sense (this is where it compares the reference address)
=== checks if two objects are exactly identical, right down to the memory address that stores the data.

To put this in real-world terms, consider the following: if your cubicle-mate swaps one of your $20 bills with another legitimate $20 bill, you don’t really care, as you’re only concerned about the value of the object.

However, if someone stole the Magna Carta and created an identical parchment copy of the document in its place, that would matter greatly because the inherent identity of the document is not the same at all.

You can use the same thought process when deciding whether to use reference types; usually there are very few times when you really care about the inherent identity — that is, the memory location — of the data. You usually just care about comparing the data values.

You want to create a shared, mutable state

Sometimes you want a piece of data to be stored as a single instance and accessed and mutated by multiple consumers.

A common object with a shared, mutable state is a shared bank account. You might implement a basic representation of an account and person as follows:

If any joint account holders add money to the account, then the new balance should be reflected on all debit cards linked to the account:

Since Account is a class, each Person holds a reference to the account, and everything stays in sync.