Modern iOS Native Development: 15 Core Interview Questions
The iOS ecosystem has evolved significantly with Swift Concurrency (async/await, Actors) and SwiftUI. Candidates interviewing for intermediate or senior iOS roles must demonstrate deep mastery over Swift value semantics, memory management retention structures, layout engines, and asynchronous processing. Here are 15 core questions.
Questions Quick Links
Q1. Explain the differences between struct and class in Swift. Where does memory allocation occur?
Answer:
- Struct (Value Type): Copied on assignment. Memory is allocated on the **Stack**, which is extremely fast to allocate and deallocate.
- Class (Reference Type): Shared references. Memory is allocated on the **Heap**, requiring reference counting overhead.
Q2. What are Actors in Swift Concurrency? How do they prevent data races?
Answer:
An actor is a reference type (similar to a class) that isolates its state. It guarantees that only a single thread can access its mutable properties at any given time, preventing data race conditions by forcing external callers to suspend execution via await.
Q3. What is the difference between a Task and a Detached Task in Swift Concurrency?
Answer:
- Task: Inherits context details (priority, task-local values, actor execution context) from the parent scope.
- Detached Task: Unbound execution. Does not inherit priority or actor context from the parent scope, running independently.
Q4. What is Automatic Reference Counting (ARC)? How do weak and unowned resolve retain cycles?
Answer:
ARC automatically tracks object references, freeing heap memory when reference counts drop to zero. If two objects hold strong references to each other, they cannot be deallocated (Retain Cycle).
Declaring references as weak (optional, becomes nil when deallocated) or unowned (non-optional, assumes target is always alive) breaks the loop.
Q5. Compare @State, @Binding, @StateObject, and @ObservedObject in SwiftUI.
Answer:
@State: Local value state managed by SwiftUI.@Binding: Reads and writes to a state property owned by a parent view.@StateObject: Instantiates and owns an external `ObservableObject`, surviving view updates.@ObservedObject: References an `ObservableObject` owned elsewhere; can be recreated during view updates.
Q6. How does the SwiftUI Layout Engine calculate sizing?
Answer:
- The parent view proposes a size constraint to the child view.
- The child view determines its own size based on its content and rules, returning it to the parent.
- The parent places the child view in its coordinate system.
Q7. Detail the lifecycle of a UIKit UIViewController.
Answer:
loadView(): Creates or loads the controller's root view.viewDidLoad(): View is loaded in memory. Excellent for startup configuration.viewWillAppear(): View is about to be displayed.viewWillLayoutSubviews(): Auto Layout is about to reposition components.viewDidLayoutSubviews(): Layout math is complete. Safe to measure final views.viewDidAppear(): View is displayed on the screen.
Q8. Compare Combine's CurrentValueSubject and PassthroughSubject.
Answer:
CurrentValueSubject: Holds a single state value and replays it immediately to new subscribers.PassthroughSubject: Does not hold state. Only emits events to active subscribers at the moment of send.
Q9. What is Core Data? What is the role of NSManagedObjectContext?
Answer:
Core Data is an object graph manager and persistence framework. NSManagedObjectContext acts as a scratchpad in memory. Changes to objects are held in the context until you call `save()`, which flushes updates to SQLite.
Q10. How do you implement custom drawings in UIKit vs. SwiftUI?
Answer:
- UIKit: Subclass
UIViewand overridedraw(_ rect: CGRect), using Core Graphics. - SwiftUI: Use the
Canvasview, which provides a drawing context directly inside the declarative layout.
Q11. What is the difference between frame and bounds in UIView?
Answer:
- frame: Sizing and position of the view relative to its **parent** view's coordinate space.
- bounds: Sizing and position of the view relative to its **own** coordinate space (origin is typically `(0,0)`).
Q12. What is App Sandboxing on iOS? Describe container paths.
Answer:
Sandboxing isolates app data. Using file paths:
Documents/: Persistent user data (automatically backed up to iCloud).Library/Caches/: Deletable app cache files (not backed up).tmp/: Temporary file dumps. Cleaned by the OS when the app is inactive.
Q13. How do you implement Keychain Services in Swift?
Answer:
Use Swift wrapper libraries or Security APIs. Save, update, or load values using query dictionaries with service identifiers:
Q14. What are GCD Queues? Compare Main and Global Queues.
Answer:
- Main Queue: Serial queue running strictly on the main thread. Responsible for all UI updates.
- Global Queue: Concurrent queues provided by the system, organized by Quality of Service (QoS) classes: `.userInteractive`, `.userInitiated`, `.utility`, and `.background`.
Q15. What is the role of the @escaping annotation in Swift?
Answer:
An escaping closure (`@escaping`) is a closure passed to a function that is executed *after* the function returns (e.g. asynchronous network responses). Escaping closures capture reference properties, requiring strong reference cycle avoidance by using capture lists: `[weak self]`.