When would you still use a class in a Swift-first codebase?

1.1.4 · L5 · Interview

Predict first

Does this compile?

struct FileBox {
    let fd: Int32
    deinit { close(fd) }
}
  • Yes
  • No

Predict first

What does this print?

final class Counter { var n = 0 }
struct Tally { let counter = Counter() }

let a = Tally()
let b = a
b.counter.n += 1
print(a.counter.n)
  • 0
  • 1
  • Compile error

Mental model. You do not choose a class because “I might subclass later”. You choose it because something must be one shared thing.

Use a class when you need shared mutable identity that value copies would break: a socket, a video player, a URLSession, a cache. Also when you need deinit for a non-memory resource, must subclass a UIKit/AppKit type, must expose the type to Objective-C, or a framework hands you one.

Actor is increasingly the right answer when that shared identity also needs isolation. A class is the right answer when it must cross an API that predates concurrency, or when the type is genuinely a UI object with a main-thread contract.

A copyable struct has no single owner, so there is no moment to run deinit. Deterministic cleanup is a reason to reach for a class (or a ~Copyable struct).

Copying the struct copies the reference. Both tallies share one Counter. “Always use structs” does not remove sharing; it hides it.

Common traps

  • “Classes are for big objects, structs for small ones.” Size is irrelevant. Identity and sharing are what matter.
  • “Always use structs” as a rule. It produces giant value types wrapping references, and re-creates the sharing bug the rule was meant to prevent.

They might follow up with

  • What about deinit in a struct? Not available. If cleanup must be deterministic, either use a class or defer at the call site.
  • Can an actor be a UI type? Only if it is @MainActor-isolated; otherwise every call hops off the main thread.

Related questions

  • 1.1.1 What is the difference between a value type and a reference type in Swift? When do you choose each?
  • 1.1.2 What is the difference between struct, class, and actor?
  • 1.1.5 How do you design a public Swift type: struct vs class vs actor vs enum?

← Where do value types live — stack or heap?   How do you design a public Swift type: struct vs class vs actor vs… →