SwiftQA Random

What happens at compile time vs runtime in Swift?

Compile time

  1. Type checking and inference
  2. Static/direct dispatch resolution
  3. Generic specialization (when possible)
  4. Sendable / isolation checking
  5. Memory layout decisions for concrete, non-resilient types
  6. Witness table and vtable construction
  7. @objc bridging surface generation
  8. #selector, #file, #line literals
  9. ABI-level calling conventions (resilient vs @frozen)

Runtime

  1. Dynamic dispatch resolution — the actual choice of which function pointer to call
  2. ARC retain/release counting
  3. Copy-on-write triggering (isKnownUniquelyReferenced)
  4. Existential container behavior — which concrete type is currently held
  5. Actor serialization / task scheduling
  6. Resilient type field access via runtime accessors
  7. Objective-C message dispatch (objc_msgSend)
  8. Type metadata queries (is, as?, type(of:), reflection)

The genuinely blurry middle ground

  • Generic code compiled unspecialized — compile-time decision, runtime witness table lookup.
  • @frozen vs resilient — compile-time decision that determines the shape of runtime behavior for every client forever.
  • Reentrancy in actors — isolation rules enforced at compile time, but manifestation depends on runtime task interleaving.

A framework for answering this live

Test: does this depend on the concrete runtime state of the program, or is it purely a function of the source code’s static shape?

Summary table

Compile timeRuntime
Type checking, generic constraint verificationARC retain/release counting, deinit timing
Sendable/isolation checkingTask scheduling, actor serialization
Static dispatch resolution, generic specializationVtable/witness-table lookup result
Layout decisions for concrete/frozen typesCOW uniqueness checks, existential boxing
Witness/vtable table constructionobjc_msgSend method lookup for dynamic
@objc bridging surface generationResilient type field access
#selector/compiler literalsis/as?/type(of:) runtime queries

One-liner if pressed: “Swift resolves as much as possible statically — types, generic specialization, Sendable/isolation safety, static dispatch, memory layout for concrete types — and defers to runtime only what genuinely depends on execution state: which concrete type an existential holds, reference counts and COW uniqueness, and task/actor scheduling.”