Instruction

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In this instruction, you’ll learn about other important topics in Swift: struct and class.

In the previous lesson, you learned that functions are a way to group lines of code into a single unit. Structs and classes group functions and variables together to form an object.

You already used them in the first lesson. You used uppercased, lowercased, and replacing functions inside String. Those three functions, among many others, are defined under String to provide functionality related to it.

You declare a Swift struct like this:

struct NameOfStruct {

}

This is a struct with the name NameOfStruct. It is convention that objects like struct and class get names with a leading capital letter, whereas regular functions and variables begin with a lowercase letter. You now have a data type with that name and can create variables with it:

var variableOfStruct: NameOfStruct

This creates a variable with the name variableOfStruct and the data type NameOfStruct. But that doesn’t give an initial value to the variable. To do that, you use the constructor or otherwise called, an initializer. It uses the name of the data type as a function whose return value is a fresh value of that type:

var variableOfStruct: NameOfStruct = NameOfStruct()

You can omit the explicit data type from the variable declaration because you’re using its constructor:

var variableOfStruct = NameOfStruct()

Classes are defined the same way, with the class keyword:

class NameOfClass {

}

var variableOfClass = NameOfClass()

Both structs and classes can contain variables and functions:

struct NameOfStruct {
  var exampleVariable: Int

  func exampleFunction() {

  }
}

To access variables or functions inside a struct, you access them through a variable instance of that struct:

var variableOfStruct = NameOfStruct()

variableOfStruct.exampleVariable
variableOfStruct.exampleFunction()

Both structs and classes can contain variables, constants and functions with input parameters and output. The main difference between an instance of a class and an instance of a struct is how they hold their values in memory.

Structs are called value types, and classes are reference types. So what does that mean?

To answer that, you need to understand a little of how memory works when you create a variable.

When you create a variable with a data type that is a struct, memory gets assigned directly for it. Then, when you create another variable and set it to the value of the first one, another area in memory is assigned to it and the memory content of the first is copied to the new variable.

var variableOfStruct_1 = NameOfStruct()
var variableOfStruct_2 = variableOfStruct_1

Using the constructor allocates the necessary memory for the object. When you assign the value from one variable to the other, both store the same value, which is expected.

variableOfStruct_1 variableOfStruct_2

Class types have similarities and some differences. The constructor also allocates the necessary memory for the object, but the variable itself isn’t where the value is stored. It’s a reference to the memory address where the value is stored.

var variableOfClass_1 = NameOfClass()
var variableOfClass_2 = variableOfClass_1

Setting the value of a second variable to the first sets its value. But it’ll be a new space in memory that holds the same address of the value in the first variable. Both variables refer to the same area in memory, so their values are always equal.

variableOfStruct_1 variableOfClass_1 variableOfClass_2 variableOfStruct_2

Value types directly access the memory location where their value is saved. Every time you assign a value type to another variable, it gets copied.

Reference types hold the address, and the value is saved somewhere else. Every time you assign a reference type to another variable, the address gets copied.

You might think it doesn’t make sense to have this indirect access for reference types, but you might be surprised by how useful it is.

Reference types allow multiple variables to access the exact same value; when that value changes through one of them, they can all see the new value. Value types correspond one-to-one with the values. Each variable has its own copy of the value, and if one variable changes the value, the others won’t know about that change.

Deciding when to use a class or a struct can feel like a big decision, but it’s not as complicated as you might think. Here’s a basic checklist to guide you in this decision:

  • Does the type contain only variables and no functions? If yes, then it’s recommended to be a struct.
  • Does it need to be centralized and does it not make sense to have copies of it? If yes, then it should be a class.

The data types you’ve used so far — Int, Float, Double, String, and even arrays — are all structs. Swift is most efficient when individual data pieces are value types rather than reference types.

When you create a type that’s going to hold a number of data pieces and change that data, you probably want a reference type. When you want multiple screens to all point to the same data and reflect any changes immediately, you definitely want a reference type.

Data Screen Screen Screen Screen

As you can see from the diagram, it already looks like multiple references are accessing the same value. Each screen should have a reference to the data to be able to modify it, and the data is centralized for all the screens. If the data store was a value type, each screen would have its own copy of the data. Changes made by one screen would not reflect on the others, and you’d end up with multiple versions of the data which would be very confusing for the user. You can see a reference type is the correct choice in this case.

In the next demo, you’ll use both data types to build a contacts app in a playground. You’ll be able to create multiple contacts and store them together in a phonebook. That phonebook will allow you to search for a contact and return the results of that search.

See forum comments
Download course materials from Github
Previous: Introduction Next: Class & Struct Demo