Class vs Struct in Swift
By: Burak Akyalçın
Tags: Objective C, Apple, iOS, Swift, Programming

When we need to decide how to store data and model behavior, there are two choices: Classes and Structs. In this article, I will explain which type should be preferred in different situations.

Classes and Structs may look like the same person at first glance

Let’s talk about what they can offer in common.

They both define properties to store values. If we want to create an object with some properties and behaviors, we can use both of them.

Both of them define subscripts so we can reach their values via subscript syntax.

Classes and structs have initializers to create instances with initial values.

Conforming to protocols are also in common. Some protocols may be class only so only classes can conform to that protocol, otherwise both can conform it.

Finally, they can be extended.

Classes yet have some extra capabilities that structs don’t have.

They can inherit another classes characteristics.

A class can free up assigned resources by deinitializers.

So, what about the differences?

The main difference between those two is that Classes are reference type, Structs are value type objects. Okay but what does it mean?

Do you remember that cartoon? :)

What is a reference type?

When we are initializing an object, RAM allocates memory space and address to it. Then, assigns its memory address to the object we created.

Let’s see this with an example.

We have an Animal class that only has a name property. Then, we create a dog object and create cat object but assign dog to the cat object.

Since they are reference type objects, they are pointing to the same memory address, so they are actually the same objects! If we change one of their property, other one will be affected as well because they are pointing to the same address. Let’s take a look below.

class Animal { var name: String init(name: String) { self.name = name } }

var dog = Animal(name: “dog”) var cat = dog

print(dog.name) // prints "dog" print(cat.name) // prints "dog"

dog.name = “hound”

print(cat.name) // prints "hound"

A note from Swift official documentation

Unlike value types, reference types are not copied when they are assigned to a variable or constant, or when they are passed to a function. Rather than a copy, a reference to the same existing instance is used.

What is a value type?

Another note from Swift official documentation

A value type is a type whose value is copied when it’s assigned to a variable or constant, or when it’s passed to a function.

Period. It is that simple.

Let’s see the above example with minor modifications.

struct Animal { var name: String init(name: String) { self.name = name } } var dog = Animal(name: “dog”) var cat = dog

print(dog.name) // prints "dog" print(cat.name) // prints "dog"

dog.name = “hound”

print(cat.name) // prints "dog"

When to use classes?

We need to use classes when we need Objective-C interoperability. If we use an Objective-C API that receives data from our side, those data must be a class because Objective-C doesn’t have structs.

Another use case for classes is when we need to control identity. If we need an instance of an object through the app and we want to control its identity, classes are the solution.

When to use structs?

Almost anytime. We must use structs by default to represent common kinds of data. Structs in Swift are powerful and have many features. They have stored properties, computed properties and methods. Also, they can conform to protocols and gain their behaviors. Many of types from Foundation and the Swift standard library are structs; for example strings, arrays, numbers and dictionaries.

Structs help you track a portion of your code since they are value types. We only need to focus to the area where the struct is used, because there is not any object that points to struct’s address and manipulate it. Otherwise we need to look at possible places that may change our object’s value.

Apart from classes, we should use structs when we don’t control identity. Think about fetching data from server, there may be same objects but since we are not controlling identity, we better use structs.

References: