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 = "归零了!"
}
}
}