Classes and structures in Swift

Classes and structures in Swift
Swift language introduced a significant improvement of structures, and thus in many cases made them an interesting alternative to classes. Quite many functionalities of classes and structures are similar, but there are a few differences and because of them it is a good idea to consider which of these forms is more useful in what situation.

Common features of classes and structures

  • properties storing specific values,
  • defining methods in order to provide functionalities,
  • defining subscripts through which you can gain access to a selected value,
  • initializers, with which we set up initial state,
  • extending functionalities beyond a default implementation,
  • can adjust to protocols.

The most important differences

  • classes support inheritance, whereas structures don’t,
  • for a class we can define deinitializers,
  • classes are a type passed by a reference, whereas structures are passed by a value.

Creating an instance of both class and structure is very similar. It only differs in the key word – class or struct. We can access their values in the same way. We will however notice the difference when creating an instance. For a structure, based on all its properties, an memberwise initializer will be automatically created. For example, for the structure:

struct Coordinates {
	var x : Float
	var y : Float
	var z : Float
}

there will be created a following initializer:

var myCoordinates = Coordinates(x: , y: , z: )

for which we need to fill the values of x, y, z.

Due to the fact that a class is a reference type, and a structure a value type, they will behave differently when an already created object will be assigned to a new instance and when an operation on this instance will be executed. For example, for the above-mentioned structure:

var myCoordinates = Coordinates(x: 0 , y: 0, z: 0)
var anotherCoordinates = myCoordinates
anotherCoordinates.x = 22

After execution of these operations, the value of x is still 0 for myCoordinates, whereas for anotherCoordinates it is 22. This is due to the fact that at the time of the assignment of myCoordinates to anotherCoordinates there was passed not a reference to the object, but its copy. At the time of execution of corresponding operations on class instances, the value of the x variable would be 22 in both cases.

If we use an instance of a structure as a method parameter, we also sent a copy, therefore changes made during the execution of the method will be stored only locally in its scope. If we want changes to be used in our instance globally, we need to mark the method parameter as inout.

With this tag, the changes performed during the execution of the function will be assigned to the parameters passed to the function by a value.

func changeCoordinates(inout coordinates: Coordinates) {
	coordinates.x = 88
	coordinates.y = 100
}

changeCoordinates(&myCoordinates)

After performing such actions values of x and y in myCoordinates instance will be 88 and 100. It should be noted that in this case, contrary to standard passing of function parameters, a parameter myCoordinates is preceded with &.

Another notable difference is in results of defining an instance of a class or a structure as a constant. In case of a class, after creating an object constant we can’t change the object to which it refers, but we can edit the properties of the object assigned to this constant. For a structure also properties of an object are unchangeable. This is illustrated by the following example:

  • for class:
After performing such actions values of x and y in myCoordinates instance will be 88 and 100. It should be noted that in this case, contrary to standard passing of function parameters, a parameter myCoordinates is preceded with &.

Another notable difference is in results of defining an instance of a class or a structure as a constant. In case of a class, after creating an object constant we can't change the object to which it refers, but we can edit the properties of the object assigned to this constant. For a structure also properties of an object are unchangeable. This is illustrated by the following example:

for class
  • for structure:
let myCoordinates = Coordinates(x: 0 , y: 0, z: 0)
var anotherCoordinates = myCoordinates
myCoordinates = anotherCoordinates  // error
myCoordinates.x = 22 // also error

Structures also introduce a security related to methods that alter properties of that structure. Adding a method:

func increaseByTwo() {
	self.x = self.x + 2
}

to the discussed structure is not allowed, as it changes the self parameter. To enable a method to perform such operations we should add to it the keyword “mutating”.

mutating func increaseByTwo() {
	self.x = self.x + 2
}

Now, compiler will no longer consider this method an error.

Looking at various possibilities offered by structures and classes a question arises of when to use a structure and when to choose a class. Apple’s documentation mentions that the primary purpose of a structure is to store relatively simple values. At the time of passing an instance of a structure, these values should be the values which we want to copy and not give references of. When choosing we should also remember about the fact that structures do not support inheritance.

As good examples of using a structure there were listed:

  • dimensions of geometric shapes,
  • all sorts of coordinates.

If you encounter a suitable candidate for a structure, you should use it, as for objects containing only a few simple values its performance is better than performance of a class.

 

You should also mind that in Swift arrays and dictionaries are also structures. Due to that, at the moment of assigning one instance of an array to another array data is copied, and as a result a change in one array is not reflected in the other. In Objective-C to get such behavior we had to intentionally create an array using the copy method.

Learn more

iOS Small Talks: PubNub – solution for the real-time communication

We encounter applications running in real time pretty much everywhere. Any chat or a game uses this technology. Creating communication that is based on the assumption that what is happening in reality should be immediately reflected in the application, is unfortunately neither easy nor cheap. However for small applications we don't need to spend huge money on dedicated infrastructure. PubNub can help us.
Read more

Project estimation

Check out how we use our knowledge in practice, and make your project with us.

Why choose us?

Logo Mobile Trends Awards

Mobile Trends Awards 2017

Nomination in M-commerce category

17

clients reviews

Clutch logo
Logo Legalni bukmacherzy

Legal Bookmakers Award 2019

Best Mobile App

60+

projects in portfolio