tezvyn:

Copy-on-Write (CoW) in Swift

AI-drafted, machine-checkedSource: swift.orgintermediate

Copy-on-write lets Swift's Array, Dictionary, Set, and String share one underlying buffer across copies until one is mutated, giving full value-type semantics with the performance of sharing, deferring the actual copy until it is truly needed.

WHY IT EXISTS Swift promises that value types like arrays and dictionaries behave as if each variable owns an independent copy: mutating one should never affect another that was assigned from it. Implemented literally, that would mean duplicating the entire backing buffer on every assignment and every function call, which is wasteful when most copies are never mutated at all. Copy-on-write exists to deliver the promised value semantics while paying the real cost of copying only when a shared buffer is actually about to be written to.

THE MENTAL MODEL It behaves like a shared document's make-a-copy button that does not actually duplicate anything until someone starts typing. Until then, everyone with a copy is really just looking at the same underlying file. The instant one person edits, only then does a private copy split off for them, and everyone else keeps looking at the original, untouched version.

HOW IT WORKS Array, Dictionary, Set, and String wrap an internal class-based storage buffer, and classes in Swift are reference types. Assigning one array variable to another copies only the reference to that buffer and increments its retain count, so both variables point at one shared buffer. Any mutating method, like append, first calls isKnownUniquelyReferenced on the buffer's reference. If the retain count is greater than one, meaning it is shared, the method allocates a new buffer, copies the existing elements into it, and mutates that new buffer, leaving the original buffer, and whatever other variable still points at it, completely unchanged. If the reference is already unique, the method skips the copy and mutates the existing buffer directly.

WHEN IT MATTERS It matters for performance-sensitive code that passes large collections around: pure reads cost nothing extra no matter how many variables reference the same buffer. The footgun shows up in two places: write-heavy code that fans a collection out to many owners and mutates each one pays for a real allocation and copy per first mutation, and sharing a collection reference across threads without synchronization is unsafe, because the uniqueness check itself is not thread-safe.

ONE CONCRETE EXAMPLE An array holding 1, 2, 3 assigned to a second variable leaves both pointing at one buffer with a retain count of two. Appending a fourth value through the second variable finds the buffer shared, allocates a new buffer, copies in 1, 2, 3, appends 4, and only the second variable changes. The first variable still reads exactly 1, 2, 3.

Read the original → swift.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.