ProgrammingiOS Developer

How does stack allocation and heap allocation work in Swift? In which cases are objects placed on the stack or the heap, how does this affect performance and the lifecycle of objects?

Pass interviews with Hintsage AI assistant

Answer

In Swift, value types (such as struct, enum, and tuple) are usually allocated on the stack, whereas reference types (such as class) are allocated on the heap.

Stack allocation is fast, automatic, and used for storing local variables with a short lifetime. Heap allocation requires additional overhead and is used for objects with an indeterminate lifetime or size.

Example:

struct Point { var x: Int; var y: Int } let p1 = Point(x: 2, y: 3) // On the stack class Node { var value: Int; init(value: Int) { self.value = value } } let n1 = Node(value: 5) // In the heap

Details:

  • The Swift compiler/optimizer can place even structs in the heap if they are nested within a class or placed in a collection.
  • Value types are copied when passed, which typically leads to copying on the stack, but Swift implements copy-on-write for collections.
  • Heap allocation requires management of the object lifetimes (ARC). Stack objects are automatically destroyed when they go out of scope.

Performance: Stack allocation is faster as it does not require dealing with heap memory and managing object lifetimes.

Trick Question

Do all structures (struct) always reside exclusively on the stack?

Answer:
No! While structures are value types and are often placed on the stack, the compiler may store them in the heap if they are part of a class, an array, a dictionary, or used as captured values in closures. For instance:

class Box { var point: Point init(point: Point) { self.point = point } } let box = Box(point: Point(x: 1, y: 2))

Here, the instance of Point will be stored in the heap, as it belongs to the class Box.

Real-World Example of Mistakes Due to Lack of Understanding


Story

A developer tried to optimize the performance of structures, believing that large structures would always be in the stack, and did not account for the fact that collections (Array, Dictionary) use heap allocation, leading to unexpected memory usage increases in the project.


Story

In the project, they did not consider that closures capture the value of a structure, which ends up in the heap, affecting the object's life. This increased the lifetime of variables and led to memory leaks as they expected automatic release when going out of scope.


Story

Using arrays of heavy structures without understanding copy-on-write led to unexpectedly expensive copy operations due to passing collections between threads, reducing performance and causing UI delays.