Hacking the iOS Interview

Swift — Structs vs Classes — Part I

Shivam Pandey
Hash Coding
Published in
5 min readFeb 16, 2021

--

Swift struct vs class interview questions
Photo by Austin Distel on Unsplash

This forms a very common question for almost all iOS interviews. This is because it plays a significant role in choosing the right abstraction mechanism keeping both performance and modeling in mind. Questions can range from areas covering consistency of data as well as the performance of the app.

What are structs and classes?

Structs and classes are like a template or prototype that contains the variables and the methods common to all objects of that kind. These help in keeping the code organized for easier maintenance and reusability.

What are class only features in Swift as compared to structs?

  • Inheritance: a class can inherit the characteristics of another class.
  • Type-casting: helps in checking and interpreting the type of a class instance at runtime.
  • Deinitializers: enable an instance of a class to free up any resources it has assigned.
  • Reference counting: allows more than one reference to a class instance.

What are value types vs reference types?

  • Value types: Each instance keeps an independent copy of its data, for example — structs, enums or tuples. Changing one instance will have no effect on the other.
  • Reference types: Instances share a single copy of the data. Changing data in one instance will change the data for all the instances pointing to the same instance, for example — classes.

When to use struct vs class in Swift?

When creating a new model, we need to carefully contemplate the use cases of the model. Based on this, we should decide between structs and classes.

Use structs when:

  • Comparing instance data with == makes sense
    This means when only data needs to be compared, and memory locations of these data are not important.

In the above example, it is important to compare the value of the NetworkRequest’s urls and not the memory addresses.

  • You want copies to have an independent state
    Take the above example and modify it a little by assigning request1 to request2, and changing the url of request2 only.

We can see that both the requests have different urls as each request have a different copy of the urls.

  • The data will be used in code across multiple threads
    When passing and copying the value types in a multi-threaded environment we can be sure that each context will have a separate unique copy which will not impact the others. This can help avoid a lot of unintentional bugs.

Use classes when:

  • Comparing instance identity with === makes sense
  • You want to create a shared, mutable state
    If we want to share the state among the threads and variables then use classes.

Where are structs and classes allocated in memory?

Structs are allocated in the stack memory.
References of the class objects can be created on the stack but all the properties of that class’ object will be kept in the heap.

Reference counting in classes vs structs?

Since classes support heap allocations they need to maintain reference counts for allocating and deallocating objects.
Structs do not need reference counting. However, if structs contain references then they would incur twice the number of reference counting overhead as compared to a class.

Method Dispatching in classes vs structs?

Classes use method dispatch. But if a class is marked as final, the compiler will use static dispatch.
Structs use static dispatch.

What are memberwise initializers?

Memberwise initializers are those initializers which the compiler generates automatically for structs. We can initialize a struct’s object using these initializers even though we have not provided any custom initializers.

The order of the arguments in these initializers is decided by the order of the declared properties in the struct.

However, if we write any custom initializer, the compiler will not generate the memberwise initializer.

If we want both memberwise and custom initializers, we should add the custom initializer in the extension of that struct.

Also, I would suggest iOS developers to read the official Swift documentation to know more about the initialization process in Swift.

What is the “mutating” keyword in Swift and when is it used?

When we have to change any property of a struct, we should use the mutating keyword before the func keyword when defining a method. This is because the self parameter that’s implicitly passed into every method is immutable by default.

Within a mutating method, self is passed as a var. The mutating keyword helps the compiler to decide which methods cant be called on let constants. If we try to call a mutating method on a let variable, the compiler shows an error.

Swift mutating keyword usage example
When creating request2 as a let variable — compiler gives an error.

It’s just tip of the iceberg. I have a lot to cover on this topic, so divided this story into two parts. Many advanced concepts and questions of structs and classes in swift can be found here: Swift — Structs and Classes — Part II.

Apart from this, one should also be aware of Swift’s Copy on Write optimization when dealing with value types, and how we can implement Copy on Write for our own custom types.

Keep following!

If you like the content, save it on medium and share with your iOS community and help us reach a larger audience who could use this. You can appreciate it as well. Clap or Claps. 👏 👏

Get notified every time we post a new story to our publication. Follow us now

We are dedicated to our goal to help every iOS developer grow and give their best in the interview. Every week we’ll be coming up with newer topics. Don’t miss them. Signup Now. ✉️

--

--

Shivam Pandey
Hash Coding

Lead Engineer iOS @airtelxlabs | Editor: Hash Coding