Swift: Beware of Computed Properties

Yesterday, I accidentally stumbled into yet another cool Swift feature: Computed Properties. I saw it used by someone else in their code, and found the syntax confusing enough at the time to think it did something different than it does!

A computed property is essentially a function disguised as a property. Here is an example:

var width = 100.0
var height = 100.0

// this is the computed property!
var area: Double {
    return width * height
}

area // 10,000.0

width = 10.0
height = 10.0
area // 100.0

width = 15.0
height = 10.0
area // 150.0

In this example, area is used as a property, but it actually recalculates every single time it’s called, just like a function!

But think of what happens when the area is set. In the above case, you’ll actually get a compiler error saying you can’t set the area property (since it’s computed). But what if you still want to? You can actually split your computation between a getter and a setter:

var width = 100.0
var height = 100.0

// computing setter and getter
var area: Double {
    get {
        return width * height
    }
    set(newArea) {
        let squareRootValue = sqrt(newArea)
        width = squareRootValue
        height = squareRootValue
    }
}

area // 10,000.0

area = 500
width // 22.36
height // 22.36

area = 100
width // 10.0
height // 10.0

area = 16
width // 4.0
height // 4.0

In this example, when the area is set, the width and height properties are re-calculated to be the square root of the new area.

If you do use a computed property, make sure you have a really good reason to do so, since some other class that calls the class with the computed property might not be aware of the recalculation happening and might not expect a different result!

I’m still trying to figure out good use cases for computed properties. I’d love to hear your thoughts in the comments.

Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.

  • Jimmy Sambuo

    In general, properties are functions that are disguised as variables. The difference between computed and stored properties is that with stored properties, Swift automatically creates the field backing for you, and implements getter and setter. You can modify the implementation by using property observers, or by overriding it in a subclass.

    At least that’s how I see it.

    • George

      “Swift automatically creates the field backing for you” Actually, Swift does not actually create a backing field. You re probably thinking of Obj-C, which creates ivars beginning with an _ character.

      • Jimmy Sambuo

        I’m thinking very low level, like RAM level. Declaring a stored property would allocate memory in RAM, but declaring a computed variable should not allocate memory. It’s as if an ivar was created for you, except you cannot access it directly.

        I’m actually thinking about C#/.NET properties. Swift and C# properties seems similar for this aspect.

        • George

          Sorry, my bad. I hadn’t read your comment fully.

  • rep

    Delphi has had properties since day 1

    Properties let you transparently change the meaning of member variables without affecting consumers of that class.

    It’s essentially syntactic sugar to allow a getter/setter method appear the same as a regular member variable.

  • George

    This isn’t a Swift thing. The majority of OOP languages have getters and setters.

    • Jeremy

      They are a bit different in Swift. The pattern looks similar, but it has to be a computed property. You don’t use it to generally access private instance values like you would in other languages.

  • George

    The uses are too varied to sum up. To take the first example that comes to mind, since I was working on it this morning: I have a property: “.scrollviews_scrollpoint” and I use it to set or get the scrollpoint for 10 different scrollviews at once. It’s more convenient and readable than the alternatives.

  • green_knight

    There are two use cases off the top of my head:

    1) fullName = firstName + lastName ought to be a property since it’s entirely based on other properties.
    2) times when you want to modify the getter or setter for a property – if language == “Hungarian”{
    return full name = lastName + firstName
    }
    else

    This can become quite complex – I’ve got a bibliographic database that allows you to enter data according to its type, and always spits out a styled string.

    Basically I feel that if you will want to make a calculation that is entirely based on properties of your class (etc), it should be a property rather than a function. If it can be called with data from outside of your class, it should be a function (and might even be a part of a controller class rather than the data model).

    In short: I’m a Filemaker developer. I *like* calculated properties.

    • George

      An obvious example of “1)” is measurements. Say you have “._foo_width_pixels” – by adding computed properties for “.foo_width_cm” and “.foo_width_points” you can eliminate code in the rest of your app, and not worry about doing conversions anywhere else.

  • Erik Engheim

    Lots of cases where this is useful. E.g. if you implement a Rectangle class, you might want xmin, xmax and width as properties. However you only need 2 of them to describe the third. So one of them ought to be computed. Lots of cases like this with geometry. E.g. a Circle class might have both a radius and diameter property but each one can be derived from the other.

  • Geoff Lee

    I agree with the others here. In my opinion, computed properties should:
    1) have low amounts of operations. It should be an easy to read one-liner
    2) always return the same value given the same state. The expectation is that a property will not change unless the state of the object changes.
    3) If there is a setter, the setter should observe the same rules as the getter, including returning the same value from the getter that you do with the setter
    4) preferably just be derived values of other properties (public or private). If you follow this, the above 3 rules should always be satisfied. Example:s fullName, description, UIView.size/UIView.width/etc

    Examples of bad computed properties:
    – Random values
    – today’s date
    – a value from another object or singleton
    – formatting a date
    – fetching from server

  • Drew Cover

    This is a typical space vs time situation when you are looking for performance improvements in OOP. Take fullName = firstName + lastName as an example. If gets on fullName are frequent compared to sets to either firstName or lastName, (which would be normal in this case), you can improve performance by storing fullName and recalculating it only when firstName or lastName are set, instead of recalculating fullName on every get.

    You can also run into the opposite situation, where sets are much more frequent (model updates vs screen refreshing) than gets. Then you want sets to be cheap and gets expensive.

    The more expensive the calculation is, and the more lopsided sets vs gets is, the more important it is the put the calculation on the infrequent side.

    Sometimes though you may not actually realise a performance improvement because the optimiser has already implemented your store vs calculate improvement.

  • Zack Beach

    I like to adopt the CustomStringConvertible protocol to give objects string representations. Instead of a “toString()” function, CustomStringConvertible has a variable called “description”. I make “description” a computed variable so its content is always up-to-date.

  • Mohamed

    Another good use case would be:
    if you have an Address object that ‘AddressLine1’, ‘AddressLine2’, ‘City’, ‘ZipCode’, ‘State’.

    You would create a computed property based on a concatenation of them all.