首页 » iOS编程基础:Swift、Xcode和Cocoa入门指南 » iOS编程基础:Swift、Xcode和Cocoa入门指南全文在线阅读

《iOS编程基础:Swift、Xcode和Cocoa入门指南》3.5 setter观察者

关灯直达底部

计算变量并不需要成为存储变量门面,这一点与你想的可能会不同。这是因为Swift提供了另一个漂亮的特性,可以让你将功能注入存储变量的setter中,即setter观察者。这些函数会在其他代码设置存储变量前后被调用。

声明具有setter观察者变量的语法非常类似于声明计算变量的语法;你可以编写一个willSet函数、一个didSet函数,二者也可以都提供:


var s = "whatever" { ①    willSet { ②        print(newValue) ③    }    didSet { ④        print(oldValue) ⑤        // self.s = "something else"    }}  

①变量必须是var(不能是let)。可以为它赋初值,后跟一对花括号。

②willSet函数,如果有,那就是willSet,后跟一对花括号,里面是函数体。当其他代码设置该变量时它会被调用,就在变量接收到新值之前。

③在默认情况下,willSet函数会将接收到的新值设为newValue。你可以在单词willSet后面的圆括号中提供不同的名字来改变这一点。旧值依然位于存储变量中,willSet函数可以访问到它。

④didSet函数,如果有,那就是didSet,后跟一对花括号,里面是函数体。当其他代码设置该变量时它会被调用,就在变量接收到新值之后。

⑤在默认情况下,didSet函数会接收到旧值,它已经被变量值所替换,名字为oldValue。你可以在单词didSet后面的圆括号中提供不同的名字来改变这一点。新值已经位于存储变量中,didSet函数可以访问到它。此外,didSet函数也可以将存储变量设为不同的值。

如果存储变量被初始化了或是didSet函数修改了存储变量值,那么Setter观察者函数就不会被调用,这是个循环!

实际上,在使用Objective-C中的Setter重写的大多数情况下,相对于计算变量来说,我更倾向于使用Setter观察者。如下示例来自于Apple提供的代码(Master–Detail Application模板),它说明了一种典型场景,即在设置了某个属性后改变界面:


var detailItem: AnyObject? {    didSet {        // Update the view.        self.configureView    }}  

这是视图控制器类的一个实例属性。每次修改该属性时,我们都需要改变界面,因为界面的一部分职责是显示该属性的值。因此,每次设置属性时,我们只需调用一个实例方法即可。该实例方法会读取属性值并相应地设置界面。

如下示例来自于我所编写的代码,我们不仅要修改界面,还要将设置的值限定在一个范围内:


var angle : CGFloat = 0 {    didSet {        // angle must not be smaller than 0 or larger than 5        if self.angle < 0 {            self.angle = 0        }        if self.angle > 5 {            self.angle = 5        }        // modify interface to match        self.transform = CGAffineTransformMakeRotation(self.angle)    }}  

计算变量是没有Setter观察者的,它也不需要!有一个Setter函数,在设置值时的一些额外处理可以直接在该Setter函数中以编程的方式完成。