Menu
×
   ❮     
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS DSA TYPESCRIPT ANGULAR ANGULARJS GIT POSTGRESQL MONGODB ASP AI R GO KOTLIN SWIFT SASS VUE GEN AI SCIPY CYBERSECURITY DATA SCIENCE INTRO TO PROGRAMMING BASH RUST

Swift Basics

Swift HOME Swift Intro Swift Get Started Swift Syntax Swift Statements Swift Output Swift Comments Swift Variables Swift Data Types Swift Type Casting Swift Operators Swift Strings Swift Arrays Swift Ranges Swift If...Else Swift Switch Swift While Loop Swift For Loop Swift Break/Continue Swift Collections

Swift Types & Functions

Swift Functions Swift Optionals Swift Enums & Patterns Swift Closures Tuples & Type Aliases

Swift Object Model

Swift OOP Swift Inheritance Swift Polymorphism Swift Protocols Swift Generics Swift Extensions Access Control Initializers Deinitializers Value Semantics & COW Equatable & Comparable

Swift Robustness & Async

Swift Error Handling Swift Concurrency Swift Memory

Swift Tooling

Swift Package Manager

SwiftUI Basics

SwiftUI Intro iOS Project Setup SwiftUI Layout SwiftUI Navigation SwiftUI Data Flow SwiftUI Lists & Forms SwiftUI Animations SwiftUI Gestures SwiftUI Modifiers & ViewBuilder SwiftUI Previews SwiftUI Accessibility SwiftUI Styling & Theming

SwiftUI Data & Architecture

Networking Persistence Persistence (Core Data) MVVM Architecture AppStorage & SceneStorage Testing SwiftUI

iOS Capabilities

Privacy & Permissions Push Notifications Widgets & Extensions Background Work Core Location App Clips Keychain Basics CloudKit File System Background URLSession MapKit

iOS Quality & Compliance

Localization Accessibility App Privacy In-App Purchases Analytics & Reporting Testing with XCTest

iOS Release & Distribution

Assets & App Icons Signing & Distribution TestFlight & App Store Ship Your First App

Swift Exercises

Swift Exercises Swift Quiz

Swift Memory Management


Swift Memory Management

Understand ARC, avoid retain cycles with weak/unowned, and manage closure captures safely.


Automatic Reference Counting (ARC)

Classes are reference types.

Swift uses ARC to automatically track and release class instances when no strong references remain.

Example

class Box {
  let name: String
  init(_ n: String) { name = n; print("init \(n)") }
  deinit { print("deinit \(name)") }
}

do {
  let b = Box("A")
  print("in scope")
}
print("after scope")

Try it Yourself »

This example demonstrates ARC's automatic deallocation of the Box instance when it goes out of scope.

Tip: Use weak to avoid strong reference cycles between class instances.


Strong Reference Cycles

A strong reference cycle occurs when two class instances hold strong references to each other, preventing ARC from deallocating them.

Mark one side as weak (or unowned when appropriate) to break the cycle.

Example

class Person {
  let name: String
  var apartment: Apartment?
  init(name: String) { self.name = name }
  deinit { print("Person deinit") }
}

class Apartment {
  let unit: String
  weak var tenant: Person? // weak breaks the cycle
  init(unit: String) { self.unit = unit }
  deinit { print("Apartment deinit") }
}

do {
  var john: Person? = Person(name: "John")
  var unit: Apartment? = Apartment(unit: "4A")
  john!.apartment = unit
  unit!.tenant = john
  john = nil   // Person deinit
  unit = nil   // Apartment deinit
}

Try it Yourself »

Declaring tenant as weak breaks the cycle so both objects deallocate when their strong references are set to nil.



Closures and Capture Lists (weak self)

Closures capture variables by default.

When a class stores a closure that references self, use a capture list like [weak self] to avoid retain cycles.

Example

class Loader {
  var onComplete: (() -> Void)?
  func load() {
    // simulate async completion
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
      guard let self = self else { return }
      print("Finished: \(self)")
      self.onComplete?()
    }
  }
  deinit { print("Loader deinit") }
}

do {
  let loader = Loader()
  loader.onComplete = { print("done callback") }
  loader.load()
}
// loader can be deallocated if nothing else references it

Try it Yourself »



×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
sales@w3schools.com

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
help@w3schools.com

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Copyright 1999-2025 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.