Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Intermediate Swift Extensions and Protocols Protocol Conformance Through Extensions

ells tang
ells tang
278 Points

Is it an extension of var regarded as a func in Swift?

// Plz Help ^^ So my code as below:

protocol UniquelyIdentifiable {
    var uuid:Int { get }
}
import UIKit
extension UIView: UniquelyIdentifiable {
    var uuid:Int {
        print(hash)   //here the Xcode console tells me "Missing return in a function expected to return 'Int'"
    }
}

so I am wondering that according this rule, is it that a var object in extension object would always be regarded as a func ? or is there something I misunderstood.

1 Answer

Michael Hulet
Michael Hulet
47,912 Points

In Swift, every var isn't technically just a box thats stores some data. Swift automatically generates getter and setter methods for all variables. They both do exactly one thing by default; the getter returns the current value of the variable and the setter sets the value of a variable to something passed in. When you get or set the value of a variable property of an object, you never directly get or set the value itself, but the Swift compiler automatically calls the proper getter or setter method to get or set the value for you. If you want, you can override the getter and/or setter of a property by doing something like this:

var someVariable: Any{
    get{
        // This is the getter
    }
    set{
        // This is the setter
    }
    willSet{
        // This is the willSet observer
    }
    didSet{
        // This is the didSet observer
    }
}

Code in the getter is run every time some code asks for the value of someVariable (in the code above). It's important to note that if you override the getter of a variable, Swift considers it to be a computed property, and it no longer actually allocates memory to store a value. Code in your getter should generate the value it returns from the value(s) of other variables and/or functions, and any value that the variable would've otherwise stored is inaccessible. A variable's getter always returns a value of the type of the variable (Any in the code above)

Code in the setter is run every time some code tries to set the value of the variable. Inside the setter, the new value of the variable is not yet set, so if you try to get the value of the variable, it will be its old value before it's set. You can reference the intended new value of the property as newValue inside a variable's setter. If you override the setter of a variable, you must also override the getter of that variable, which means that any value the variable would otherwise store is also inaccessible. A setter always returns Void, so an explicit return statement is not necessary

If your intention is to run code whenever the value of a variable changes while still allowing it to store its own value, it's better to use a property observer. There are 2 available: willSet and didSet. didSet is called right after a variable's value is set. This is great for running code whenever a variable's value changes. In general, it's considered better form to define didSet instead of willSet, unless you need the functionality that willSet provides. willSet is called right before a variable's value is set. In the willSet observer, getting the current value of the variable will return the value of the variable before its set, and the intended new value of the variable after willSet finishes can be referenced as newValue, just like in a setter. This is perfect for cases where you wanna run code that requires both the new and old values of a variable. Defining an observer will not cause the compiler to consider it a computed property, so a backing variable will still be generated, unlike if you overrode the variable's getter or setter.

In your code, you're using the shorthand syntax to override a getter. A getter always returns a value of the type of the variable, but there's no return statement in your code, so the compiler complains. Your use case above seems like a great scenario to override didSet if your goal is to print something out, but if your scenario is to make your view's uuid property always return its hash, you should make your protocol conform to NSObjectProtocol and return hash from that getter instead. You can always print it out before you return it, too!

To learn more about getters and setters and observers and variables in general, you should take a look at The Swift Programming Language's reference for Properties