Kodeco Forums

Reference vs Value Types in Swift: Part 1/2

Value types are much more prominent in Swift compared to Objective-C. Learn the difference between reference and value types in Swift in part 1 of this tutorial.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/1506-reference-vs-value-types-in-swift-part-1-2

Hi Eric,

Thanks for the tutorial, it’s a great explanation. I do have a question though. How does the extension work?

extension Point: Equatable { }
func ==(lhs: Point, rhs: Point) -> Bool {
  return lhs.x == rhs.x && lhs.y == rhs.y
}

the func == is not inside the {} of the extension. How can this relate to Point?

I tried putting the func == inside the {} but, just get errors.

Thanks in advance.
K

Hi K,
As it is stated above “This protocol defines only one function which you must implement globally in order to compare two instances of the object.”

Equatable protocol automatically defines this function ( so you can’t see the definition in curly braces after Equatable ) which you have to implement globally just like other protocol method implementations. Hope that helps.

Thanks.

  • Vakas

Ah-ha. Of course now I see the ‘globally’ part of the sentence and see that lhs and rhs have nothing to do specifically with Point. Thanks for getting back to me.

K

I would like to express my doubts if this advice of yours is useful when choosing between struct and class:

If you’re not quite sure which mechanism applies to your situation, default to value types. You can always move to a class later with little effort.

Consider the following statement from Apple’s Swift Programming Language Book (emphasis mine):

As a general guideline, consider creating a structure when one or more of these conditions apply:

  • The structure’s primary purpose is to encapsulate a few relatively simple data values.
  • It is reasonable to expect that the encapsulated values will be copied rather than referenced when you assign or pass around an instance of that structure.
  • Any properties stored by the structure are themselves value types, which would also be expected to be copied rather than referenced.
  • The structure does not need to inherit properties or behavior from another existing type.
    

    In all other cases, define a class, and create instances of that class to be managed and passed by reference. In practice, this means that most custom data constructs should be classes, not structures.

This means that developers who will follow your advice, when in doubt, will start with struct, and in most cases will change it later to class since most of the data constructs should be classes, according to Apple. Moreover, until the developers understand that their data construct should be a class, they will write == operator, and copy-on-write code for reference types inside their struct, only to throw it away later.

I would recommend the following: before you start writing your data construct, consider if it clearly follows the guidance of Apple’s Swift Programming Language Book for choosing a struct. In such a case, define it as a struct. In all other cases use class. I would prefer to err on the side of defining a class, since most of data constructs should be classes and no additional code (== operator, copy-on-write code) is required for a class.

Another great article on struct vs. class in Swift - Should I use a Swift struct or a class? · faq.sa .

Thanks @vakas for the response, that’s exactly right. @kmt, this is the technique you use to allow two objects of a specific type to be compared against each other globally throughout your app. You’ll note that in the == function, it takes two Point objects as its parameters. You could define an Equatable function for any type you want custom comparison for as long as you supply the proper parameter types.

-E

Hey @vadime, great points you bring up. I think one of biggest things here is that generally, if you walk through all the conditions listed here for a stuct vs class, you should be pretty confident in picking one vs the other. If you are still unsure, then I still think it’s good practice to default to stuct.

I find that keeping my data constructs simple and doing most of the heavy lifting in other objects (ViewModels for example), makes using structs the perfect solution. For things like ViewModels, or any UIKit objects, classes are definitely the way to go as they may have to maintain state and be referenced by multiple objects. Data, at its core, shouldn’t need to hold a type of state that could be messed up when passed around.

If the data object needs reference type properties, then I would consider changing my architecture to avoid copy-on-write code in the first place. Generally I like having a class hold reference to struct data. The class is what interacts with the data and is referenced by other objects.

Anyways, there is definitely no full proof solution, and every situation is unique.

Thanks for the input!
-E

The last sentence before the “When To use Reference Types” seems to say the opposite of what you mean. It says:
“If threads can uniquely own the data, using value types makes
the whole point moot since each owner of the data only references the
data instead of holding a copy.”

Shouldn’t it say each owner holds a copy?

Hey @sojourner9, you’re right, definitely wrote it in reverse! Thanks for pointing that out. Made the update which should propagate through the servers eventually.

A super explanation of comparing one to the other!

This tutorial is more than six months old so questions are no longer supported at the moment for it. We will update it as soon as possible. Thank you! :]