Value Types vs Reference Types in Swift
In Swift, types fall into one of two categories: Value types and Reference types. let’s discuss in detail about them.
Value Types:
A value type is a type whose value is copied when it is assigned to a variable or constant, or when it’s passed to a function. Structures and Enumerations are value types in swift.
let’s see how Value type behaves:
When the person1 object is assigned to person2, a new copy of a Person object is created. If you do any changes in person2, it will not affect the person1 object.
In Swift, all the basic types like integers, floating-point numbers, Booleans, strings, arrays, and dictionaries are also value types and are implemented as structures behind the scenes. You can see their implementations here https://github.com/apple/swift/tree/master/stdlib/public (swift repository)
When to use Value Type?
- Comparing instance data with == makes sense
- You want copies to have an independent state
- The data will be used in code across multiple threads
Note: Creating a new copy every time when you assign a value type to a variable can be expensive because you’ll have to copy all the underlying data to another place in memory. To minimize this issue, COW(copy on write) has been implemented in the Swift standard library for some of the value types like Array and Dictionary, this enables value types to be referenced when they are assigned to other variables. The real copy only happens when you modify the value.
let array = [1,2,3] //address A
var notACopy = array //still address A
notACopy += [4,5,6] //now address B
Reference Types:
In the case of reference type, rather than creating a copy, a reference to the same existing instance is used when it is assigned to a variable or constant or passed to a function. Classes are reference types in swift.
let’s see how Reference type behaves:
When the person1 object is assigned to person2, reference of the same (person1) instance is assigned to person2, If you do any changes in person2, it will reflect in person1 object also.
When to use Reference Type?
- Comparing instance identity with === makes sense
- You want to create a shared, mutable state
Which is faster among Value Types and Reference Types?
Value types are faster than Reference types, because.
- Value Types are stored on Stack Memory. Variables allocated on the stack are stored directly to the memory and access to this memory is very fast, and its allocation happens during compilation. When a function creates a variable, the stack stores that variable and is destroyed automatically when the function exits.
- Reference Types are stored on Heap Memory. Heap is more dynamic but less efficient than the stack. The heap doesn’t automatically destroy its object, It has to be handled externally. In swift ARC is used to handle this. In ARC, the reference count of an object is tracked and once count becomes zero, the object is deallocated. This overall process of allocation, tracking the references and deallocation makes heap slower compared to stack.
So, as suggested by Apple, try to use structures(value type) to represent common kinds of data. Use class(reference type) only when you need Objective-C interoperability or you need to control the identity of the data you’re modeling.
- For reference types, the objects are stored on the heap, while their pointers are stored on the stack. For value types, the object itself is stored on the stack.
- In case a value stored on a stack is captured by a closure, that value will be moved to the heap so that it’s available till the closure is executed.
- If the value type is part of a class, the value is stored in the heap along with the class instance.
- Reference types are always saved in the Heap, whereas Value Types always go where they are declared.
Additional Information: