BLACK FRIDAY: Save 50% on all books and bundles! >>

Why do copies of a class share their data?

Paul Hudson    @twostraws   

Updated for Xcode 12.0

One feature of Swift that is truly confusing at first is how the behaviors of its classes and struct differ when they are copied: copies of the same class share their underlying data, meaning that changing one changes them all, whereas structs always have their own unique data, and changing a copy does not affect the others.

The technical term for this distinction is “value types vs reference types.” Structs are value types, which means they hold simple values such as the number 5 or the string “hello”. It doesn’t matter how many properties or methods your struct has, it’s still considered one simple value like a number. On the other hand, classes are reference types, which means they refer to a value somewhere else.

For value types, this is easy enough to understand that it’s self-evident. For example, look at this code:

var message = "Welcome"
var greeting = message
greeting = "Hello"

When that code runs, message will still be set to “Welcome”, but greeting will be set to “Hello”. As Chris Eidhof says, “this is so natural it seems like stating the obvious.” ( But that’s how structs behave: their value are wholly contained inside their variable, and not somehow shared with other values. This means all their data is stored directly in each variable, so when you copy it you get a deep copy of all the data.

In contrast, the best way to think about a reference type is that it’s like a signpost pointing to some data. If we create an instance of a class, it will take up some memory on your iPhone, and the variable that stores the instance is really just a signpost to the actual memory where the object lives. If you take a copy of the object, you get a new signpost but it still points to the memory where the original object lives. This is why changing one instance of a class changes them all: all copies of the object are signposts pointing to the same piece of memory.

It’s hard to overestimate how important this difference is in Swift development. Previously I mentioned that Swift developers prefer to use structs for their custom types, and this copy behavior is a big reason. Imagine if you had a big app and wanted to share a User object in various places – what would happen if one of those places changed your user? If you were using a class, all the other places that used your user would have their data changed without realizing it, and you might end up with problems. But if you were using a struct, every part of your app has its own copy of the data and it can’t be changed by surprise.

As with many things in programming, the choices you make should help convey a little of your reasoning. In this case, using a class rather than a struct sends a strong message that you want the data to be shared somehow, rather than having lots of distinct copies.

Save 50% in my Black Friday sale.

Sponsor Hacking with Swift and reach the world's largest Swift community!

Buy Pro Swift Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift (Vapor Edition) Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Server-Side Swift (Kitura Edition) Buy Beyond Code

Was this page useful? Let us know!

Average rating: 5.0/5

Link copied to your pasteboard.