willSet
和didSet
是swift中的属性观察者,可用于存储属性
修改时的操作。关于计算属性
和存储属性
可以查看这个文章:从一个报错说下Swift计算属性和存储属性
willSet 观察器会将新的属性值作为常量参数传入,在 willSet 的实现代码中可以为这个参数指定一个名称,如果不指定则参数仍然可用,这时使用默认名称 newValue 表示。
同样,didSet 观察器会将旧的属性值作为参数传入,可以为该参数指定一个名称或者使用默认参数名 oldValue。如果在 didSet 方法中再次对该属性赋值,那么新值会覆盖旧的值。
初始化过程不会被调用
在用的时候可能会发现某种情况下willSet和didSet不被调用,这是因为文档中提过
当一个属性首次初始化时,willSet和didSet观察者不会被调用。只有在属性值设置在初始化上下文之外时才会调用它们。
所以如果你是在初始化中这样写的,那么是不会执行的
var mIconImage:UIImage = UIImage(named: "cell_weather")! {
willSet {
self.mIconImageView.image = newValue
}
}
var mTitleText : String = "" {
willSet {
self.mTitleLabel.text = newValue
}
}
convenience init(iconImage:UIImage, titleText:String) {
self.init(frame: CGRect.zero)
self.mIconImage = iconImage
self.mTitleText = titleText
}
初始化强制调用
如果想要强制这个在初始化过程中调用呢,那么可以使用defer
延迟声明,也可以使用自定义函数,这两种方案都可行
1、使用defer
关键词
var mIconImage:UIImage = UIImage(named: "cell_weather")! {
willSet {
self.mIconImageView.image = newValue
}
}
var mTitleText : String = "" {
willSet {
self.mTitleLabel.text = newValue
}
}
override init(frame: CGRect) {
super.init(frame: frame)
self.p_createUI()
}
convenience init(iconImage:UIImage, titleText:String) {
self.init(frame: CGRect.zero)
defer {
self.mIconImage = iconImage
self.mTitleText = titleText
}
}
2、构造一个赋值的函数,在函数中调用
var mIconImage:UIImage = UIImage(named: "cell_weather")! {
willSet {
self.mIconImageView.image = newValue
}
}
var mTitleText : String = "" {
willSet {
self.mTitleLabel.text = newValue
}
}
override init(frame: CGRect) {
super.init(frame: frame)
self.p_createUI()
}
convenience init(iconImage:UIImage, titleText:String) {
self.init(frame: CGRect.zero)
self.p_loadData(iconImage: iconImage, titleText: titleText)
}
func p_loadData(iconImage:UIImage, titleText:String) -> Void {
self.mIconImage = iconImage
self.mTitleText = titleText
}
至于网上的通过KVC方法赋值后,再添加setValueforUndefinedKey方法做特殊处理的方案就不要采用了
版权属于:东哥笔记 - DongGe.me
本文链接:https://dongge.org/blog/1001.html
自2017年12月26日起,『转载以及大段采集进行后续编辑』须注明本文标题和链接!否则禁止所有转载和采集行为!
2 条评论
好高端,完全看不懂哈哈哈
用来搬砖的工具而已