Madhu Chamarty
Madhu Chamarty

Reputation: 81

What is the difference between a property and a variable in Swift?

From a few initial tutorials, I see that properties belong to a Class and are essentially 'global variables' as used in the C++ world (coded in this years ago). I also see variables as more of a 'local' entities only used / storing information within a method.

Then I came across this Quora thread: https://www.quora.com/Apple-Swift-programming-language/What-is-the-difference-between-a-property-and-a-variable Now I see properties being able to execute code associated with their invocation. This is very cool, but also opened up a whole bunch of other questions for me.

Are there other simple and clear ways to remember the distinction between a property and a variable?

Upvotes: 7

Views: 6070

Answers (3)

yoAlex5
yoAlex5

Reputation: 34175

Swift variable, constant, Property

[Swift types]

variable - named storage of address. Every variable has a type which defines a memory size, attributes and behaviours

Swift variable and constants

constant is a variable but can not be modified after definition.

//definition
var <name> = <initial_value>
//type annotation
var <name>: <Swift_type> [= <initial_value>] // [] is optional

//var - variable
var myVariable1 = 11 
var myVariable2: Int 
myVariable2 = 12

//let - constant
let myConstant1 = 21 
let myConstant2: Int 
myConstant2 = 22

Global and local variable

Global variable is a variable which is defined out of function, class. Local variable is: variable inside a type context(class, struct, enum)[About], inside a function, function parameter

Property

property - associate value with a type context. It is a variable + bounded getter/setter. It has field syntax but uses methods(getter/setter) under the hood.

Stored properties and computed properties

They can belong to instance(instance property) or type(type property):
Stored property (class, structure)
Computed property (class, structure, enum)

Stored property - is a local variable -> variable inside a type context. Swift stored property does not support instance variable like Objective-C.

  • variable stored properties - var
  • constant stored properties - let

It supports property observers (willSet, didSet)

Computed property - provide getter and optional setter to calculate a value every time

public class Person {
    var firstName = "John"
    var lastName = "Wick"
    
    var fullNameComputedProperty: String {
        get {
            return "\(firstName) \(lastName)"
        }
        
        //optional
        set {
            let arr = newValue.split(separator: " ")
            firstName = String(arr[0])
            lastName = String(arr[1])
        }
    }
    
    var addressStoredProperty: String {
        //Property Observers
        willSet {
            print("old address:\(addressStoredProperty)")
            print("new address:\(newValue)")
            //addressStoredProperty is not updated yet
        }
        didSet {
            print("old address:\(oldValue)")
            print("new address:\(addressStoredProperty)")
        }
    }
}

Lazy Stored property

Property is calculate during first access to it(on demand)

  • only var lazy because let must have a value during initialization

Init/customize stored property by closure

Official doc

You are able to init/setup/customise a stored property with a help of closure

  • () at the end executes the closure immediately and assign a value to stored property(calculate and return a value).
  • in initializing case it is not possible to access to any instance variable or function because it has not initialized yet
  • in initializing case it will be executed only once for every object or if you use static - once for the class[Example]

Examples

func testStoredPropertyWithClosure() {
    class ClassA { }
    
    class ClassB {
        static let staticStoredProperty: ClassA = {
            //is called only when you access to it like ClassB.staticStoredProperty
            print("init staticStoredProperty")
            return ClassA()
        }()
        
        var storedProperty: ClassA = {
            print("init storedProperty")
            //self.foo() //Error: Class declaration cannot close over value 'self' defined in outer scope
            return ClassA()
        }()
        
        func foo () {
            storedProperty = {
                print("customize storedProperty")
                return ClassA()
            }()
        }
    }
    
    let b = ClassB()
    b.foo()
    
    ClassB.staticStoredProperty
}

closure stored property vs Computed property

  • closure stored property is called once and can be changed after initialization(if it is var)
  • Computed property is calculated every time when it is called

[Java variable, property...]

Upvotes: 5

zneak
zneak

Reputation: 138031

Local variables are just things that you work with. You have full control over these, and if you change a variable in a function, nothing outside of your function is ever gonna know. If I write a framework and you use it, and I decide to change something about a function's local variables, your app that uses my framework will keep working just as if nothing changed.

Classes, on the other hand, describe a contract. When you use a class, you have access to everything they publicly advertise. This means that if I write a framework and you use it, if I ever change or remove a public member on a class, your code will break if you were previously using that member.

For this reason, in many languages, it's bad practice to mark instance variables as public. Instance variables having no logic attached, if I want at some point to trigger something when a field is changed or if I want to remove the field entirely (and instead report a value in a sub-object or something), then I'm stuck with changing the public contract (turning the field in a pair of get/set methods, for instance), and possibly breaking your code.

Swift makes properties an indirection for this reason. Swift properties can be treated as dumb values for the most part, but if you ever need to change from a stored value to a computed value or something, you can do it without changing your class's interface. That way, you don't break existing code that relies on the property.

Upvotes: 6

123
123

Reputation: 8951

Properties belong to an object, whereas variables do not. A variable can be declared without having to be associated with a particular class, or other object. A property must be associated with a particular object (i.e.: a class, enum, or struct)

Upvotes: 12

Related Questions