如何使用共享初始化方法初始化 let 变量?
How can I initialize a let variable using a shared init method?
我想使用 let
设置一个变量,这样它就不是可选的,不会随着时间的推移而改变,也不需要每次都进行混乱的解包访问。我知道我可以合法地设置它,但只能在 init
方法之一中进行。问题是 Swift 要求您重写 init(coder aDecoder: NSCoder)
初始值设定项。但是,我从来没有一个应用程序调用过该初始化程序。它总是调用 init(frame: CGRect)
初始值设定项。因此,如果我不必覆盖 init(coder aDecoder: NSCoder)
那么我只需在 init(frame: CGRect)
中执行 self.imageView = UIImageView.new()
就可以了,但是编译器抱怨它没有在另一个中设置初始化也是如此。我尝试制作一个从两个 init 调用的 sharedInit()
方法,但编译器不允许我从那里设置 imageView
,因为它只在 init 方法之外读取。如果不直接在 init 方法中执行所有 init 两次,您应该如何完成此操作?
class SuperCoolView : UIView {
let imageView: UIImageView
required init(coder aDecoder: NSCoder) {
sharedInit()
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
sharedInit()
super.init(frame: frame)
}
func sharedInit() {
self.imageView = UIImageView.new()
// Other similar shared init
}
}
只需结合惰性初始化和私有 'set' 即可得到:
class SuperCoolView : UIView {
public private(set) lazy var imageView: UIImageView = {
// In practice, do more here. Access state in this instance.
// Or, include more computation.
UIImageView.new()
}()
// inits w/o setting imageView
}
'private set' 使它在外部与 let
相同; lazy
允许您根据 SuperCoolView
实例中的其他状态初始化值。
请注意,如果 imageView 等的初始化不依赖于实例中的状态,那么您可以避免 lazy
并仅从闭包中进行初始化。
我找到了 this answer 并喜欢它的方法。它解决了这个问题,并且更干净恕我直言。通过正常实施 init(coder aDecoder: NSCoder)
,我们将保持外观,即此视图可以从 nib/storyboard 初始化,但它不能。
class SuperCoolView : UIView {
let imageView: UIImageView
required init(coder aDecoder: NSCoder) {
fatalError("NSCoding not supported")
}
override init(frame: CGRect) {
self.imageView = UIImageView.new()
// Other stuff
super.init(frame: frame)
}
}
我想使用 let
设置一个变量,这样它就不是可选的,不会随着时间的推移而改变,也不需要每次都进行混乱的解包访问。我知道我可以合法地设置它,但只能在 init
方法之一中进行。问题是 Swift 要求您重写 init(coder aDecoder: NSCoder)
初始值设定项。但是,我从来没有一个应用程序调用过该初始化程序。它总是调用 init(frame: CGRect)
初始值设定项。因此,如果我不必覆盖 init(coder aDecoder: NSCoder)
那么我只需在 init(frame: CGRect)
中执行 self.imageView = UIImageView.new()
就可以了,但是编译器抱怨它没有在另一个中设置初始化也是如此。我尝试制作一个从两个 init 调用的 sharedInit()
方法,但编译器不允许我从那里设置 imageView
,因为它只在 init 方法之外读取。如果不直接在 init 方法中执行所有 init 两次,您应该如何完成此操作?
class SuperCoolView : UIView {
let imageView: UIImageView
required init(coder aDecoder: NSCoder) {
sharedInit()
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
sharedInit()
super.init(frame: frame)
}
func sharedInit() {
self.imageView = UIImageView.new()
// Other similar shared init
}
}
只需结合惰性初始化和私有 'set' 即可得到:
class SuperCoolView : UIView {
public private(set) lazy var imageView: UIImageView = {
// In practice, do more here. Access state in this instance.
// Or, include more computation.
UIImageView.new()
}()
// inits w/o setting imageView
}
'private set' 使它在外部与 let
相同; lazy
允许您根据 SuperCoolView
实例中的其他状态初始化值。
请注意,如果 imageView 等的初始化不依赖于实例中的状态,那么您可以避免 lazy
并仅从闭包中进行初始化。
我找到了 this answer 并喜欢它的方法。它解决了这个问题,并且更干净恕我直言。通过正常实施 init(coder aDecoder: NSCoder)
,我们将保持外观,即此视图可以从 nib/storyboard 初始化,但它不能。
class SuperCoolView : UIView {
let imageView: UIImageView
required init(coder aDecoder: NSCoder) {
fatalError("NSCoding not supported")
}
override init(frame: CGRect) {
self.imageView = UIImageView.new()
// Other stuff
super.init(frame: frame)
}
}