iOS Swift — Cheat Sheet

Tags: swift, ios, uikit, swiftui, arc, concurrency

Level: intermediate

TL;DR: Quick reference for iOS development with Swift, covering memory management (ARC), concurrency, UI frameworks, and common interview questions.

Key concepts

ARC (Automatic Reference Counting): Swift's memory management system; automatically frees memory when instances are no longer needed.

Value vs. Reference Types: struct and enum are value types (copied on assignment), class is a reference type.

Optionals: Enums representing either a wrapped value or nil, ensuring null safety at compile time.

Protocols: Define blueprints of methods, properties, and requirements; support Protocol-Oriented Programming (POP).

Closures: Self-contained blocks of functionality; capture and store references to variables from their context.

Concurrency: Handled via GCD (Grand Central Dispatch) or modern Swift Concurrency (async/await, Task, actor).

SwiftUI vs UIKit: SwiftUI is declarative and state-driven; UIKit is imperative and event-driven.

App Lifecycle: Managed by AppDelegate and SceneDelegate, or the @main App struct in SwiftUI.

Typical questions and ready answers

Q: What is the difference between weak and unowned?R: Both prevent retain cycles. weak becomes nil when deallocated (must be optional). unowned assumes the reference is never nil and crashes if accessed after deallocation.

Q: How do you avoid a strong reference cycle in closures?R: I use a capture list like [weak self] or [unowned self] before the closure parameters to ensure it doesn't strongly hold the instance.

Q: What is Protocol-Oriented Programming (POP)?R: It is a paradigm where I use protocols and protocol extensions to compose behavior instead of relying on deep class inheritance hierarchies.

Q: Explain the difference between escaping and nonescaping closures.R: A non-escaping closure executes within the function's scope. An @escaping closure can outlive the function, commonly used in asynchronous callbacks.

Pitfalls and common mistakes

Updating the UI from a background thread (always use DispatchQueue.main.async or @MainActor).

Forgetting [weak self] in network callbacks or timers, causing memory leaks via retain cycles.

Force-unwrapping optionals with ! without checking, leading to immediate runtime crashes.

Massive View Controller (MVC) syndrome in UIKit by putting networking and business logic inside the view controller.

Snippets and commands

// Safely unwrapping an optional
if let safeValue = optionalValue {
    print(safeValue)
}

// Escaping closure for async network call
func fetchData(completion: @escaping (Result<Data, Error>) -> Void) {
    DispatchQueue.global().async {
        // simulate fetch
        completion(.success(Data()))
    }
}

// Modern Swift Concurrency (async/await)
func fetchUser() async throws -> User {
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

To review

[ ] Actor isolation and data races in Swift Concurrency.

[ ] Property wrappers (@State, @Binding, @ObservedObject) in SwiftUI.

[ ] Combine framework basics vs async/await.

References

Apple Developer Documentation

Swift Language Guide

Jarvis Interviews
Jarvis