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.
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.
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.
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.
// 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)
}
[ ] Actor isolation and data races in Swift Concurrency.
[ ] Property wrappers (@State, @Binding, @ObservedObject) in SwiftUI.
[ ] Combine framework basics vs async/await.
Apple Developer Documentation
Swift Language Guide