Which Foundation types are value types in Swift, which are classes, and what happens to mutable ObjC types?

2.9.4 · L2 · Interview

Predict first

What does this print?

let ms = NSMutableString(string: "a")
let s = ms as String
ms.append("b")
print(s, ms)
  • ab ab
  • a ab
  • a a

Mental model. Value types are photocopies you can scribble on. Reference types are the single shared whiteboard.

Foundation’s Swift overlays turned types that behave like values into structs: Data, Date, URL, UUID, IndexPath, CharacterSet, Decimal, Measurement, DateComponents, URLComponents, URLRequest. Types with identity or internal state stay classes: DateFormatter, NumberFormatter, FileManager, NSCache, OperationQueue, UserDefaults, Bundle, URLSession, Scanner, NotificationCenter.

The value/class split matters for sharing and safety: copying a struct is independent, copying a reference shares the object. Bridging a mutable Objective-C type such as NSMutableString to Swift produces a copy, so later changes to the original do not appear in the Swift value.

The bridge made an independent Swift String copy of "a". The original object then changed on its own.

Value types (struct)Reference types (class)
Data and timeDate, DateComponents, Calendar, TimeZoneDateFormatter
LocationsURL, URLComponents, URLRequestFileManager, Bundle
Numbers and textDecimal, Measurement, CharacterSetNumberFormatter, Scanner
Identity and stateUUID, IndexPathUserDefaults, NSCache, OperationQueue, URLSession

Common traps

  • Sharing a DateFormatter and changing its dateFormat from two places. It is one mutable object.
  • Expecting nsMutable as String to track later edits. It snapshots.

They might follow up with

  • How does this connect to Sendable? Value types are usually Sendable; formatters are classes and need care across tasks.
  • How do you get an NSMutableArray back? NSMutableArray(array:) from a Swift array copies the elements in.

Related questions

  • 2.9.1 What is toll-free bridging, and how do you convert between Swift and Foundation types?
  • 2.2.7 FormatStyle or DateFormatter: which do you reach for?
  • 1.1.1 What is the difference between a value type and a reference type in Swift? When do you choose each?

← What does bridging cost, and where does it show up in a profile?   How does equality work for NSObject subclasses, and why do two… →