Language & Runtime
Generics, existentials, ARC, dispatch, ABI stability, and what Swift actually does under the hood.
- How does Swift ABI stability affect app distribution and binary compatibility? ABI stability, shipped in Swift 5, let Apple embed the Swift runtime in the OS itself, shrinking binaries and enabling cross-compiler binary frameworks.
- How does Swift handle memory for value types internally? Small structs copy on the stack for free, while Array, Dictionary, and String defer the real copy through copy-on-write until a shared buffer gets mutated.
- How do generics work under the hood in Swift? Generics compile to one shared implementation dispatched via witness tables and metadata, unless the compiler sees the concrete type and specializes it.
- What are opaque return types (some) and why were they introduced? some hides a function's concrete return type from callers while the compiler still knows it exactly, avoiding existential boxing costs entirely.
- When would you use Any or AnyObject, and why should they be avoided? Any and AnyObject erase type information and cost heap boxing past 24 bytes, so they belong at real boundaries like JSON parsing or Objective-C interop.
- What are property wrappers and how have you used them in production? Property wrappers encapsulate storage and behavior behind @propertyWrapper, and projectedValue exposes a secondary value, the way SwiftUI's @State does.
- What are existentials and why are they expensive? An any Protocol value sits in a 3-word container that heap-allocates past 24 bytes, and every call goes through witness-table indirection.
- How does protocol dispatch differ from dynamic dispatch? Witness-table dispatch for protocols and vtable dispatch for classes are both dynamic, but vtables model a hierarchy, witness tables model conformance.
- What is @frozen and why does it matter for enums? @frozen locks a type's shape forever so clients can drop @unknown default and the compiler can inline its layout, at the cost of never adding a case later.
- How does Swift bridge with Objective-C? Bridging headers expose Objective-C to Swift, generated -Swift.h headers expose @objc types back, and _ObjectiveCBridgeable converts String and Array.
- How does Swift optimize enums with associated values? Swift packs an enum's case tag into spare bits of its payload when possible, so Optional of a class reference ends up exactly the size of a raw pointer.
- What happens at compile time vs runtime in Swift? Type checking, Sendable verification, and static dispatch resolve at compile time, while ARC counts and existential lookups happen at runtime.
- When are unsafe pointers justified? Unsafe pointers earn their keep at C interop, raw memory reinterpretation, or hot paths where profiling proves bounds-checking is the bottleneck.
- When would you still write Objective-C today? New Objective-C is still justified in an existing large codebase or for runtime dynamism like swizzling and heavy KVO, not for new greenfield work.
- What is the difference between a class and a struct and when would you use them? Structs are value types and copy on assignment; classes are reference types and share instances. Default to a struct until you need identity.