Which Foundation types are value types in Swift, which are classes, and what happens to mutable ObjC types?
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 time | Date, DateComponents, Calendar, TimeZone | DateFormatter |
| Locations | URL, URLComponents, URLRequest | FileManager, Bundle |
| Numbers and text | Decimal, Measurement, CharacterSet | NumberFormatter, Scanner |
| Identity and state | UUID, IndexPath | UserDefaults, NSCache, OperationQueue, URLSession |
Common traps
- Sharing a
DateFormatterand changing itsdateFormatfrom two places. It is one mutable object. - Expecting
nsMutable as Stringto track later edits. It snapshots.
They might follow up with
- How does this connect to
Sendable? Value types are usuallySendable; formatters are classes and need care across tasks. - How do you get an
NSMutableArrayback?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… →