基於Swift的iOS應用程序開發:“屬性觀察器”簡介

Swift語言中的屬性觀察器(英文原稱:Property Observer)是一個十分便利的工具,它是變量的一種延伸特性,我們可以將它的概念比做Java中的“觀察者模式”,這兩者的目的都是一致的:即一單監聽/觀察到某個對象發生了變化,就觸發一系列動作。

但是Swift中的屬性觀察器又比Java的觀察者模式更簡單易懂,實現起來也更加方便-----甚至是沒有任何Swift開發經驗的人,或者對類似於Java 的觀察者模式毫無概念的人,都能立刻理解它。

Swift的屬性觀察器包含兩種:

第一種:willSet

第二種:didSet

故名思意,這兩個觀察器分別會在變量的值即將被改變之前,以及變量的值被改變之後,立即被調用

1、如何定義屬性觀察器

定義屬性觀察器是一件非常簡單的事情。通常我們會怎麼來定義一個變量呢?可能會是下面這樣:
var changeMe:Int = 0
我們定義了一個Int型的變量,叫做“changeMe”,並且爲它賦初始值爲0
想要定義屬性觀察器,只需要在變量賦值代碼後面,直接寫一對”{}“即可:
var 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 = "歸零了!"
        }
    }
}






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章