Swift語言中的屬性觀察器(英文原稱:Property Observer)是一個十分便利的工具,它是變量的一種延伸特性,我們可以將它的概念比做Java中的“觀察者模式”,這兩者的目的都是一致的:即一單監聽/觀察到某個對象發生了變化,就觸發一系列動作。
但是Swift中的屬性觀察器又比Java的觀察者模式更簡單易懂,實現起來也更加方便-----甚至是沒有任何Swift開發經驗的人,或者對類似於Java 的觀察者模式毫無概念的人,都能立刻理解它。
Swift的屬性觀察器包含兩種:
第一種:willSet
第二種:didSet
故名思意,這兩個觀察器分別會在變量的值即將被改變之前,以及變量的值被改變之後,立即被調用
1、如何定義屬性觀察器
var changeMe:Int = 0
我們定義了一個Int型的變量,叫做“changeMe”,並且爲它賦初始值爲0var changeMe:Int = 0{
willSet{
//...
}
didSet{
//...
}
}
這樣以來,我們就爲變量“changeMe”添加了一對屬性監聽器2、如何使用屬性觀察器
首先來看一下以下的一段關於willSet的代碼:
var changeMe: Int = 0 {
willSet {
print("changeMe 的值是 \(changeMe),即將被改變成 \(newValue)")
}
}
可以看到,在willSet的內部,用到了一個叫做“newValue”的變量,但是我並沒有在任何地方定義過它
實際上,“newValue”是willSet的一個默認參數。
我們也可以爲willSet設置一個自定義的參數:
var changeMe: Int = 0 {
willSet(newInt) {
print("changeMe 的值是 \(changeMe),即將被改變成 \(newInt)")
}
}
在上面的代碼中,關鍵詞willSet的後面多了一對(),在這對()內部,我定義了一個參數,叫做“newInt”,然後就可以在willSet內部使用這個參數了
用同樣的方式,可以使用didSet:
var changeMe: Int = 0 {
didSet {
print("changeMe 的值原來是 \(oldValue),現在是 \(changeMe)")
}
}
didSet同樣有一個默認參數,叫做“oldValue”,它記錄了變量被改變之前的原值。
我們同樣可以爲didSet設置一個自定義的參數:
var changeMe: Int = 0 {
didSet(oldInt) {
print("changeMe 的值原來是 \(oldInt),現在是 \(changeMe)")
}
}
當然了,willSet和didSet是可以同時出現的:var changeMe: Int = 0 {
willSet {
print("changeMe 的值是 \(changeMe),即將被改變成 \(newValue)")
}
didSet{
print("changeMe 的值原來是 \(oldValue),現在是 \(changeMe)")
}}
我做了一個簡單的示例,它是這樣的:
我把這個示例的整段代碼粘貼在這裏:
//
// 這個類演示了屬性監聽器的使用方式
//
// DemoPropertyObserverViewController.swift
// MyDemo
//
// Created by freezingxu on 2017/7/17.
// Copyright © 2017年 freezingxu. All rights reserved.
//
import UIKit
class DemoPropertyObserverViewController: UIViewController {
// MARK: 屬性
/**
* 用來測試屬性觀察器的變量
*/
var changeMe:Int = 0 {
willSet{
self.textFieldBeforeSet.text = "變化前:\(changeMe),即將變成:\(newValue)"
}
didSet{
self.textFieldAfterSet.text = "變化前:\(oldValue),變化後:\(changeMe)"
}
}
/**
* 在這個文本輸入框中,將會顯示變量的最終結果
*/
@IBOutlet weak var textFieldFinally: UITextField!
/**
* 當變量的值被改變前的一瞬間,會在這個文本輸入框中顯示一些文字
*/
@IBOutlet weak var textFieldBeforeSet: UITextField!
/**
* 當變量的值被改變之後,會在這個文本輸入框中顯示一些文字
*/
@IBOutlet weak var textFieldAfterSet: UITextField!
// MARK: 生命週期
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: 自定義方法
/**
* 當用戶按下按鈕的時候,會調用到本方法
* 變量的值會發生變化,並且觸發屬性觀察器,將觀察結果顯示在界面上
*/
@IBAction func tryPropertyObserver(_ sender: Any) {
self.changeMe += 1
self.textFieldFinally.text = "變量的最終值:\(self.changeMe)"
if self.changeMe > 9 {
self.changeMe = 0
self.textFieldFinally.text = "歸零了!"
}
}
}