在我的新iOS Swift应用程序中,我在我的一个UIViewControllers
中编写了以下代码片段。
var starButtonsCount = starButtons.count
@IBOutlet var starButtons: [UIButton]!
然后直接在starButtonsCount
变量声明旁边跟随错误出现在红色。
错误:无法在属性初始值设定项中使用实例成员'starButtons';属性初始化程序在'self'可用之前运行。
所以我发现通过将starButtonCount
变量声明为lazy
,我们可以解决这个错误(从iOS应用程序开发过程的长期来看是暂时的)。
我很想知道解决这个问题的其他方法是什么?
当starButtonCount
IBOutlets初始化时,有没有办法触发starButtons
的初始化?
awakeFromNib
是一个方法,当.xib中的每个对象都被反序列化并且所有出口的图形连接时调用。文件说:
宣言
func awakeFromNib()
讨论
从nib存档重新创建的每个对象的消息,但仅在存档中的所有对象都已加载并初始化之后。当一个对象收到一个awakeFromNib消息时,它保证已经建立了所有的出口和动作连接.nib-loading基础设施发送一个
awakeFromNib
您必须调用awakeFromNib的超级实现,以便为父类提供执行所需的任何其他初始化的机会。虽然此方法的默认实现不执行任何操作,但许多
UIKit
类提供非空实现。您可以在自己的awakeFromNib
方法中随时调用超级实现。
如:
class MyUIViewController : UIViewController {
var starButtonsCount = 0
@IBOutlet var starButtons: [UIButton]!
override func awakeFromNib() {
super.awakeFromNib()
starButtonsCount = startButtons.count
}
}
另请注意,starButtonsCount
不需要是存储变量:
var starButtonsCount: Int {
return starButtons.count
}
在这种情况下,最好直接使用starButtons.count
,因为变量不会改进代码。
在一般情况下,不需要存储派生状态,除非存储它提供一些性能提升(例如,高速缓存计算)。
其他方式
var starButtonsCount:Int!
@IBOutlet var starButtons: [UIButton]! {
didSet {
starButtonsCount = starButtons.count
}
}
简单的解决方案是不变的
let starButtonsCount = 8 // or whatever the number of buttons is
IBOutlets
在构建时连接,因此按钮的数量在运行时不会改变。
您可以在viewDidLoad
中添加断言行,以便在应用的未来版本中更改按钮数时获取通知
assert(starButtons.count == starButtonsCount, "number of buttons has changed, adjust starButtonsCount")