假定派生自UIView以下类的类:
UIView
class MyView: UIView { var myImageView: UIImageView init(frame: CGRect) { super.init(frame: frame) } init(coder aDecoder: NSCoder!) { super.init(coder: aDecoder) } ...
如果我想在两个初始化器中都使用相同的代码,例如
self.myImageView = UIImageView(frame: CGRectZero) self.myImageView.contentMode = UIViewContentMode.ScaleAspectFill
并且 不要 在类实现中 重复 两次 该代码 ,我将如何构造init方法?
init
尝试的方法:
func commonInit()
super.init
myImageView
正如GoZoner所说,将变量标记为可选将起作用。这不是一种非常优雅的方法,因为您每次访问该值时都必须解开该值。
我将向Apple提出增强请求,也许我们可以得到类似“ beforeInit”方法的信息,该方法在每次可以分配变量的init之前调用,因此我们不必使用可选的var。
在此之前,我将所有分配都放到commonInit方法中,该方法从专用的初始化程序中调用。例如:
class GradientView: UIView { var gradientLayer: CAGradientLayer? // marked as optional, so it does not have to be assigned before super.init func commonInit() { gradientLayer = CAGradientLayer() gradientLayer!.frame = self.bounds // more setup } init(coder aDecoder: NSCoder!) { super.init(coder: aDecoder) commonInit() } init(frame: CGRect) { super.init(frame: frame) commonInit() } override func layoutSubviews() { super.layoutSubviews() gradientLayer!.frame = self.bounds // unwrap explicitly because the var is marked optional } }
多亏了戴维(David),我再次看了一本书,发现了一些不必使用可选变量hack就能对重复数据删除工作有所帮助的东西。可以使用闭包来初始化变量。
使用闭包或函数设置默认属性值 如果存储的属性的默认值需要一些自定义或设置,则可以使用闭包或全局函数为该属性提供自定义的默认值。每当初始化属性所属类型的新实例时,都会调用闭包或函数,并将其返回值分配为属性的默认值。这些类型的闭包或函数通常会创建与属性相同类型的临时值,定制该值以表示所需的初始状态,然后返回该临时值以用作属性的默认值。 这是有关如何使用闭包提供默认属性值的框架概述: class SomeClass { let someProperty: SomeType = { // create a default value for someProperty inside this closure // someValue must be of the same type as SomeType return someValue }() } 请注意,闭包的末大括号后跟一对空括号。这告诉Swift立刻执行关闭。如果省略这些括号,则尝试将闭包本身分配给属性,而不是闭包的返回值。 注意 如果使用闭包来初始化属性,请记住在执行闭包时实例的其余部分尚未初始化。这意味着您无法从闭包内部访问任何其他属性值,即使这些属性具有默认值也是如此。您也不能使用隐式的self属性,或调用实例的任何方法。 摘录自:苹果公司“ The Swift Programming Language”。iBooks。https://itun.es/de/jEUH0.l
使用闭包或函数设置默认属性值
如果存储的属性的默认值需要一些自定义或设置,则可以使用闭包或全局函数为该属性提供自定义的默认值。每当初始化属性所属类型的新实例时,都会调用闭包或函数,并将其返回值分配为属性的默认值。这些类型的闭包或函数通常会创建与属性相同类型的临时值,定制该值以表示所需的初始状态,然后返回该临时值以用作属性的默认值。
这是有关如何使用闭包提供默认属性值的框架概述:
class SomeClass { let someProperty: SomeType = { // create a default value for someProperty inside this closure // someValue must be of the same type as SomeType return someValue }() }
请注意,闭包的末大括号后跟一对空括号。这告诉Swift立刻执行关闭。如果省略这些括号,则尝试将闭包本身分配给属性,而不是闭包的返回值。
注意
如果使用闭包来初始化属性,请记住在执行闭包时实例的其余部分尚未初始化。这意味着您无法从闭包内部访问任何其他属性值,即使这些属性具有默认值也是如此。您也不能使用隐式的self属性,或调用实例的任何方法。
摘录自:苹果公司“ The Swift Programming Language”。iBooks。https://itun.es/de/jEUH0.l
从现在开始,我将使用这种方式,因为它不会绕过不允许对变量使用nil的有用功能。对于我的示例,它将如下所示:
class GradientView: UIView { var gradientLayer: CAGradientLayer = { return CAGradientLayer() }() func commonInit() { gradientLayer.frame = self.bounds /* more setup */ } init(coder aDecoder: NSCoder!) { super.init(coder: aDecoder) commonInit() } init(frame: CGRect) { super.init(frame: frame) commonInit() } }