如何初始化IBOutlet时初始化变量?

问题描述 投票:4回答:4

在我的新iOS Swift应用程序中,我在我的一个UIViewControllers中编写了以下代码片段。

var starButtonsCount = starButtons.count
@IBOutlet var starButtons: [UIButton]!

然后直接在starButtonsCount变量声明旁边跟随错误出现在红色。

错误:无法在属性初始值设定项中使用实例成员'starButtons';属性初始化程序在'self'可用之前运行。

所以我发现通过将starButtonCount变量声明为lazy,我们可以解决这个错误(从iOS应用程序开发过程的长期来看是暂时的)。

我很想知道解决这个问题的其他方法是什么?

starButtonCount IBOutlets初始化时,有没有办法触发starButtons的初始化?

ios swift iboutlet initializer
4个回答
2
投票

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
    }
}

2
投票

另请注意,starButtonsCount不需要是存储变量:

var starButtonsCount: Int {
   return starButtons.count
}

在这种情况下,最好直接使用starButtons.count,因为变量不会改进代码。

在一般情况下,不需要存储派生状态,除非存储它提供一些性能提升(例如,高速缓存计算)。


1
投票

其他方式

var starButtonsCount:Int! 
@IBOutlet var starButtons: [UIButton]! { 
    didSet { 
         starButtonsCount = starButtons.count
    }
}

1
投票

简单的解决方案是不变的

let starButtonsCount = 8 // or whatever the number of buttons is

IBOutlets在构建时连接,因此按钮的数量在运行时不会改变。

您可以在viewDidLoad中添加断言行,以便在应用的未来版本中更改按钮数时获取通知

assert(starButtons.count == starButtonsCount, "number of buttons has changed, adjust starButtonsCount") 
© www.soinside.com 2019 - 2024. All rights reserved.