Observers in swift

851 views Asked by At

After creating a class of Triangle and used a read-only computed property named isEquilateral that will determine if equal like this

    class Triangle {
    var a: Int
    var b: Int
    var c: Int
    // initialization stuff
    var isEquilateral: Bool {
    return (sideA, sideB) == (sideB, sideC)
    }
}

how can I add an observer to check if the lengths changes, from let's say a different type of triangle? Do I add it inside the computed property (isEquilateral) or outside?

3

There are 3 answers

3
Jimmy James On

As said in this tutorial:

In your case:

var a: Int {
    willSet {
        // First time set
    }
    didSet {
        // Value changed
    }
}
var b: Int ...
var c: Int ...

This method works for me few time

2
Ahmad F On

Property Observer is what are you looking for:

Property observers observe and respond to changes in a property’s value. Property observers are called every time a property’s value is set, even if the new value is the same as the property’s current value.

So let's say you want to observe the changing of a property, you can implement it as:

class Triangle {
    var a: Int? {
        willSet {
            print("the new value is about to be: \(newValue)")
        }
        didSet {
            print("the old value was: \(oldValue)")
        }
    }

    var b: Int?
    var c: Int?

    // initialization stuff

    // ...
}

Calling (tracing):

let myTriangle = Triangle()

myTriangle.a = 10
// this will print:
// the new value is about to be: Optional(10)
// the old value was: nil (nil because it's optional...)

// re-assign a new value:

myTriangle.a = 20
// this will print:
// the new value is about to be: Optional(20)
// the old value was: Optional(10)

As you can see, it will let you know that the value of a has been changed, also it telling what are the old and new values.

So, by implementing a as a property observer, you can add your custom behavior when changing the value of a property; Let's say -for example- you want to let c is to be equals to the new value of a if it changes:

var a: Int? {
        willSet {
            print("the new value is about to be: \(newValue)")
            b = newValue
        }
        didSet {
            print("the old value was: \(oldValue)")
        }
    }

Or -another example- you want to call a function to do something when changing the value of a:

var a: Int? {
    willSet {
        print("the new value is about to be: \(newValue)")
        doSomething()
    }
    didSet {
        print("the old value was: \(oldValue)")
    }
}

private func doSomething() {
    print("doing something...")
}

For more information, I recommend to check Apple Documentation - "Property Observers" section.

Hope it helped.

0
Sasha Kozachuk On

You can use notification center if you want to track changes outside of class. Example:

class Triangle {
var a: Int {
    didSet {
        NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: "aValueChanged"), object: self))
    }
}

func randomFunc() {
    a = 20
}
}

And catch those notifications:

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.someFunc), name: NSNotification.Name(rawValue: "aValueChanged"), object: nil)
triangle.something()

And method that receives notification:

func someFunc(notification: Notification) {
    let triangle = notification.object as! Triangle
    print("a value to \(triangle.a)")
}

This is will allow you to check changes outside of the class. Output will be a value changed to 20