Difference in value and reference type property setters

swift_logoSwift properties associate values to a certain class, structure or enumeration. There are two kinds, stored and computed properties. Stored properties are constant or variable values that exist in an instance. Computed properties do not store a value, instead they represent a value that is calculated from other values. Another difference between the two is that stored properties cannot be contained in enumerations. Classes and structures can contain both stored and calculated properties.

Computed properties use a getter to calculate their value and an optional setter to manipulate other values indirectly. This is very convenient for encapsulation, i.e. restricting direct access to some member variables.

This is pretty straightforward but there is one important difference regarding setters for reference and value types.

Consider a simple reference type defined as below.

Now let’s use a trivial implementation to restrict access to stored property using a computed property.

In the Xcode Playground let’s instantiate MyClass and a new reference type instance, and assign it to myReferenceType property of myClass.

As expected and seen in the playground image below, the setter of the computed property is called.

MyReferenceTypeSetterPlaygroundExample

Now let’s try to update the name property of myReferenceType using both a method, and accessing the property value directly.

In the two lines above, the name value is mutated by changing it’s value directly, and using a function that updates the name value. As expected, in neither of the cases the myReferenceType setter of MyClass is triggered, as seen in the image below.

MyReferenceTypePlaygroundExample

Let’s consider using a value type in the same scenario of changing it’s value directly, and using a mutating function.

In this case, as seen in the image below, even though the value inside the struct is accessed and mutated, the setter of the myValueType property in MyClass is triggered. This occurs both when changing the myClass.myValueType.name directly, and using the mutating function.

MyValueTypePlaygroundExample

Let’s test this concept on an Array, which is also a value type.

As in the previous example, the names property setter in MyClass is called both for changing the array directly using myClass.names = [“a”, “b”, “c”], and also with the mutating append function.

ArrayPlaygroundExample

This means when working with different properties, it’s very important to be aware of their type. Different behavior will be observed for reference and value types.

Playground is available here.

If you liked this blog post I’d appreciate if you followed me on Twitter

Related Post

Remember to share...Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInEmail this to someone

Leave a Reply

Your email address will not be published. Required fields are marked *