问题
Apple's docs指定:
首次初始化属性时,不会调用
willSet和didSet观察器。只有在初始化上下文之外设置属性值时,才会调用它们。
是否可以在初始化过程中强制调用这些函数?
为什么?
假设我有这样一个类
class SomeClass {
var someProperty: AnyObject {
didSet {
doStuff()
}
}
init(someProperty: AnyObject) {
self.someProperty = someProperty
doStuff()
}
func doStuff() {
// do stuff now that someProperty is set
}
}
我创建了doStuff
方法,以使处理调用更加简洁,但我宁愿只处理didSet
函数中的属性。有没有办法在初始化过程中强制调用它?
更新
我决定只删除我的类的方便初始化器,并强制您在初始化后设置该属性。这让我知道didSet
总是会被调用。我还没有决定总体上这样做是否更好,但它很适合我的情况。
发布于 2014-08-11 01:10:44
创建自己的set-Method并在init-Method中使用它:
class SomeClass {
var someProperty: AnyObject! {
didSet {
//do some Stuff
}
}
init(someProperty: AnyObject) {
setSomeProperty(someProperty)
}
func setSomeProperty(newValue:AnyObject) {
self.someProperty = newValue
}
}
通过将someProperty
声明为
:
AnyObject!
(一个隐式展开的可选类型),您可以在不设置someProperty
的情况下允许self完全初始化。当您调用setSomeProperty(someProperty)
时,您正在调用一个与self.setSomeProperty(someProperty)
等效的函数。通常你不能这样做,因为self还没有完全初始化。由于someProperty
不需要初始化,并且您正在调用依赖于self的方法,因此Swift离开初始化上下文,didSet将运行。
发布于 2015-11-29 13:54:22
如果您在初始化器中使用defer
,用于更新任何已初始化的可选属性或进一步更新已初始化的非可选属性,并且在调用任何super.init()
方法之后,将调用您的willSet
、didSet
等。我发现这比实现单独的方法更方便,你必须跟踪在正确的地方调用。
例如:
public class MyNewType: NSObject {
public var myRequiredField:Int
public var myOptionalField:Float? {
willSet {
if let newValue = newValue {
print("I'm going to change to \(newValue)")
}
}
didSet {
if let myOptionalField = self.myOptionalField {
print("Now I'm \(myOptionalField)")
}
}
}
override public init() {
self.myRequiredField = 1
super.init()
// Non-defered
self.myOptionalField = 6.28
// Defered
defer {
self.myOptionalField = 3.14
}
}
}
将会产生:
I'm going to change to 3.14
Now I'm 3.14
发布于 2015-04-08 05:51:01
作为Oliver答案的一种变体,您可以将这些行包含在闭包中。例如:
class Classy {
var foo: Int! { didSet { doStuff() } }
init( foo: Int ) {
// closure invokes didSet
({ self.foo = foo })()
}
}
编辑: Brian Westphal的回答是更好的imho。他的好消息是它暗示了他的意图。
https://stackoverflow.com/questions/25230780
复制相似问题