在调用super.init时未初始化'self.*'属性

22

我刚把我的Xcode升级到了6.3.1。问题是自从Swift 1.2以后,我一直收到一个奇怪的错误信息。我一直在收到这种类型的错误信息

/Users/MNurdin/Documents/iOS/xxxxx/Library/SideBar.swift:32:15: Property 'self.originView' not initialized at super.init call

/Users/MNurdin/Documents/iOS/xxxxx/Library/SideBar.swift:38:20: Immutable value 'self.originView' may only be initialized once

在这段代码上

let originView:UIView?

override init() {
        super.init() //error here

    }

    init(sourceView:UIView, menuItems:Array<String>){
        super.init() //error here
        originView = sourceView //error here

1
这可能是你的问题:https://dev59.com/qonda4cB1Zd3GeqPCa2s#29632026 - ABakerSmith
3个回答

28

在任何初始化方法中调用super.init之前,您必须先初始化所有属性

因此,在调用super.init()之前更改此设置

originView = sourceView //error here

异常:

  1. 可选属性
  2. 带有默认值的属性
  3. 延迟属性

我已经初始化了我的属性。请检查我的问题。仍然出现错误。 - Nurdin
1
这个答案似乎不太符合问题中的代码。在这种情况下,问题不在于值被赋值的位置,而在于你不能使用 let 声明可选属性。 - John Montgomery

16

通过使您的 originView 可为空来

var originView: UIView?. 
如果你的originView不可为空,在调用之前必须提供默认值。
super.init().

1
你声明了originView为常量,使用了"let"。但是它应该是"var"。当你使用"let"时,除了在声明期间之外,你将不被允许再次更改它的值。 - Nitheesh George
你是正确的,抱歉我的错误。让我先试一下。 - Nurdin

6

来自苹果公司的《Swift编程语言》书籍:

“Swift的编译器执行四个有用的安全检查,以确保两阶段初始化完成且无误。”

“指定初始化程序必须确保在委托给超类初始化程序之前,其类引入的所有‘属性’都已初始化。”

基本上,您必须确保实例变量处于一致状态,然后再执行任何操作,包括调用方法。

class YourClass {
    var view: UIView
    init(view: UIView) {
        self.view = view
    }
}

在你的情况下,你可以创建一个新的UIView

let originView = UIView()

或者将其设置为可为空。
let originView: UIView?

或者可以创建一个"懒加载属性":
lazy var originView: UIView = {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: 375, height: 200))
    // customize it
    return view
}()

使用延迟实例化时,您可以传递一个方法:
lazy var originView: UIView = self.createView()

func createView() -> UIView {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: 375, height: 200))
        // customize it
        return view
}

什么是更好的实践?使用nullable还是lazy属性? - Edgar
2
@Edgar 这取决于实际情况。没有最佳方法,你需要考虑你的类应该如何运作,它应该具有哪些状态,并根据信息编写代码。首先尝试在纸上描述你的类,然后再编写代码,很快你就会自动地在脑海中完成所有操作。 - Oleh Zayats

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接