Skip to main content

Swift Memory Management

Automatic Reference Counting (ARC)

Overview

class Person {
let name: String
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}

var reference1: Person?
var reference2: Person?

reference1 = Person(name: "John")
reference2 = reference1
reference1 = nil
// John is still in memory because reference2 holds a strong reference
reference2 = nil
// John is now deinitialized

Strong Reference Cycles

class Department {
let name: String
var head: Employee?

init(name: String) {
self.name = name
}
}

class Employee {
let name: String
weak var department: Department?

init(name: String) {
self.name = name
}
}

Memory Management Patterns

Weak References

class Tutorial {
weak var delegate: TutorialDelegate?
// Rest of the implementation
}

protocol TutorialDelegate: AnyObject {
func tutorialDidFinish(_ tutorial: Tutorial)
}

Unowned References

class Customer {
let name: String
var card: CreditCard?

init(name: String) {
self.name = name
}
}

class CreditCard {
let number: UInt64
unowned let customer: Customer

init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
}

Best Practices

1. Closure Capture Lists

class ViewModel {
var data: [String] = []
var updateHandler: (() -> Void)?

func setupHandler() {
updateHandler = { [weak self] in
guard let self = self else { return }
print("Data count: \(self.data.count)")
}
}
}

2. Proper Resource Management

class ResourceManager {
var resource: ExpensiveResource?

func beginWork() {
resource = ExpensiveResource()
}

func endWork() {
resource = nil // Explicitly release the resource
}
}

Common Memory Issues

1. Retain Cycles

  • Identifying retain cycles
  • Using memory graph debugger
  • Breaking retain cycles

2. Memory Leaks

  • Common causes
  • Detection tools
  • Prevention strategies

Next Steps

  1. Explore Protocol-Oriented Programming
  2. Study Testing and Debugging