Class vs Struct in Memory | iOS & Swift

Kim Arnett  - Mar 20 '20 - - Dev Community

Hey everyone, long time no blog! What better time to get back at it then between the two week span of being laid off and facing a global pandemic, am I right? So, to stay grounded I offered the following, in which someone asked a great question, that I felt like deserved a blog post instead of a quick response. Mostly because I have to remind myself of the answer multiple times a year. :)

Question is: Mutability in Structs vs Classes

If you're cruising around an iOS codebase, chances are you've come across some objects declared as structs, and some declared as classes. What gives? If you've googled for an answer, you probably found something talking about reference types or value types and other boring programming words. I'm going to cover the basics of what you need to know. If you want to dive deeper, by all means please do! Here's a great starting point from Apple's Swift docs on Structures vs Classes.

High level: Structs copy data, classes mutate data.

Let's experiment with structs:

Here I've defined a simple example, one variable.
Full playground example down below

struct exampleStruct {
    var varA = 0
}
Enter fullscreen mode Exit fullscreen mode

If we create two instances of exampleStruct, we can see that changing one does not change the other.

var myFirstStruct = exampleStruct()
var mySecondStruct = exampleStruct()

myFirstStruct.varA = 100
print(myFirstStruct.varA)   //100
print(mySecondStruct.varA)  //0
Enter fullscreen mode Exit fullscreen mode

If we assign the first struct to the second struct, we might expect that it would point to the same memory instance as the first struct, and therefore change with it. Let's see..

mySecondStruct = myFirstStruct
myFirstStruct.varA = 200

print(myFirstStruct.varA)   //200
print(mySecondStruct.varA)  //100
Enter fullscreen mode Exit fullscreen mode

Whaaat. Actually what happened was the second struct took a copy of the first struct in a new memory slot. Meaning, it adopted the values that existed in first struct at the time of copy, but by saving them into a new memory slot, it copies/duplicates and therefore does not adopt any new values assigned to first struct.

Let's experiment with classes:

Another simple example, one variable.

class exampleClass {
    var varA = 0
}
Enter fullscreen mode Exit fullscreen mode

If we create two instances of exampleClass, we can see that changing one does not change the other, same as structs.

var myFirstClass = exampleClass()
var mySecondClass = exampleClass()

myFirstClass.varA = 100
print(myFirstClass.varA)    //100
print(mySecondClass.varA)   //0
Enter fullscreen mode Exit fullscreen mode

So far so good. If we assign the first class to the second class, will it point to the same memory instance as we expected before? Or will it copy like structs? Let's see..

mySecondClass = myFirstClass
myFirstClass.varA = 200

print(myFirstClass.varA)    //200
print(mySecondClass.varA)   //200
Enter fullscreen mode Exit fullscreen mode

The second class pointed to the same memory slot as the first class object, thus aligning them to any values that change going forward.

mySecondClass.varA = 300
print(myFirstClass.varA)    //300
print(mySecondClass.varA)   //300
Enter fullscreen mode Exit fullscreen mode

Thanks for checking this out! There are some other differences worth checking out, again a good place to start is the Swift docs linked above.

Full playground example here:

struct exampleStruct {
    var varA = 0
}

//STRUCT EXAMPLE - Start with two
var myFirstStruct = exampleStruct()
var mySecondStruct = exampleStruct()

myFirstStruct.varA = 100
print(myFirstStruct.varA)   //100
print(mySecondStruct.varA)  //0

mySecondStruct = myFirstStruct
myFirstStruct.varA = 200

print(myFirstStruct.varA)   //200
print(mySecondStruct.varA)  //100


print("-----------------")

class exampleClass {
    var varA = 0
}


//CLASS EXAMPLE
var myFirstClass = exampleClass()
var mySecondClass = exampleClass()

myFirstClass.varA = 100
print(myFirstClass.varA)    //100
print(mySecondClass.varA)   //0

mySecondClass = myFirstClass
myFirstClass.varA = 200
print(myFirstClass.varA)    //200
print(mySecondClass.varA)   //200

mySecondClass.varA = 300
print(myFirstClass.varA)    //300
print(mySecondClass.varA)   //300
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .