← All topics/Swift language features

Practical interview questions

Scenario-style prompts with sample answer outlines. Focus is on how you would design and reason in real codebases.

Question 1

Value vs reference semantics — struct, class, actor

When would you choose a struct vs a class vs an actor for a model type in an iOS app? What are the tradeoffs for identity, mutation, and concurrency?

Answer outline

Structs are value types: assignment logically copies (often optimized with copy-on-write). Prefer them for domain values, == semantics, and predictable copies.

They cannot inherit or participate in classic retain cycles the way classes can and as such are more suitable for Protocol-oriented-programming.

Classes are reference types: shared identity (===), inheritance, and Objective-C interop.

Use when you need shared mutable state or reference semantics. ARC applies; retain cycles with closures and delegates are a real risk.

Actors are reference types with isolated mutable state and compiler-enforced serial access.

They should be used for concurrent shared resources, not for every model.

SwiftUI view models are often structs; observable state may live in an ObservableObject (with Combine framework) or @Observable class on the main actor.

Struct vs Class vs Actor — key differences in type semantics, thread safety, and typical iOS use cases.

Principles

  • Prefer structs for pure data and predictable copy behavior; classes for identity and shared lifecycle.
  • Actors solve mutation under concurrency. They are not a drop-in replacement for classes in UI hierarchies.
Struct — value semantics
struct Point: Equatable {
    var x: Double
    var y: Double
}

var a = Point(x: 0, y: 0)
var b = a
b.x = 1
// a is unchanged; independent copies
Class — shared reference
final class UserSession {
    var token: String
    init(token: String) { self.token = token }
}

let s1 = UserSession(token: "a")
let s2 = s1
s2.token = "b"
// s1.token is also "b" — same instance
Actor — serialized access
actor Counter {
    private var value = 0
    func increment() { value += 1 }
    func current() -> Int { value }
}

func useCounter() async {
    let counter = Counter()
    await counter.increment()
    _ = await counter.current()
}

Follow-up angles

  • SwiftUI: view bodies are structs; observable state often lives in ObservableObject or @Observable types.
  • Bridging to Obj-C: classes subclass NSObject.