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
- Explore Protocol-Oriented Programming
- Study Testing and Debugging