[Swift] Property observers willSet and didSet

What is a property observer?

When the value of the stored property is updated, you can write the process with that as a trigger. For example, by using a property observer When the value of var price = 100 is updated, it is possible to write a process to count the number of updates. This property observer has a willSet that is called just before the value changes and a didSet that is called after the change. You can write only one of these. The way to write is as follows.

var property name:Mold=initial value{
    willSet (Formal argument) {
Process called immediately before change
   }
    didSet (Formal argument) {
Process called immediately after change
   }
}

Each formal argument

Formal arguments can be specified for willSet and didSet respectively. With willSet, you can refer to the new value immediately before being stored in the property with a formal argument. If you omit the formal argument, you can refer to it with the name newValue. With didSet, you can refer to the old value previously stored in the property with a formal argument. If you omit it, you can refer to it with oldValue.

I tried using willSet

I entered the purchase amount in the textField and created an app that displays the difference between the number of times and the previous amount when the button is pressed.

class ViewController: UIViewController {
    @IBOutlet var label: UILabel!
    @IBOutlet var priceTextField: UITextField!
    @IBOutlet var countLabel: UILabel!
    @IBOutlet var hikakuLabel: UILabel!
    var count = 0
    var  priceDifference = ""
    let minPrice = 1.0
    
    var buyingPrice: Double = 0 {
        willSet {
            count += 1
            guard newValue > buyingPrice else {
                priceDifference = "From last time\(buyingPrice - newValue)Yen low purchase price"
                return
            }
            priceDifference = "From last time\(newValue - buyingPrice)High purchase price"
        }
    }

    @IBAction func countUpButton(_ sender: Any) {
        buyingPrice = Double(priceTextField.text!) ?? 0
        countLabel.text = "The number of purchases\(count)Times"
        hikakuLabel.text = priceDifference
    }
}
Execution result

I was able to get the number of purchases in willSet, calculate the price difference and display it.

スクリーンショット 2021-01-06 19.55.20.png

スクリーンショット 2021-01-06 19.55.44.png

スクリーンショット 2021-01-06 19.56.06.png

I tried using didSet

Use didSet to set a minimum number and try to write code so that it doesn't go below that.

class ViewController: UIViewController {
    @IBOutlet var numberTextFIeld: UITextField!
    @IBOutlet var numberLabel: UILabel!
    let minNumber = 1
    
    var seisuu:Int = 1 {
        didSet {
            if seisuu < minNumber {
                seisuu = minNumber
            }
        }
    }

    @IBAction func button(_ sender: Any) {
        seisuu = Int(numberTextFIeld.text!) ?? 0
        numberLabel.text = String(seisuu)
    }
}
Execution result

When a number is set in the variable seisuu, if it is below the minimum value, it is specified to be the minimum value, so when the button is pressed, a number below 1 can be displayed as 1.

スクリーンショット 2021-01-06 20.33.24.png Even if you enter -30, it is displayed as 1. ↓ スクリーンショット 2021-01-06 20.33.46.png

merit

By using these, the code becomes quite compact. You can hold and retrieve the value without creating another field.

References

https://qastack.jp/programming/24006234/what-is-the-purpose-of-willset-and-didset-in-swift

Takeshi Ogiwara, "Detailed Swift 5th Edition", SB Creative Co., Ltd., November 25, 2019, p. 557

Recommended Posts

[Swift] Property observers willSet and didSet
[Swift] Constants and variables
Use swift Filter and Map
[Swift] Type component ~ Property Part 2 ~