为什么类的init方法中不需要隐式可选项?

时间:2017-05-30 22:06:46

标签: swift automatic-ref-counting optional

我正在关注Ray Wenderlich网站上关于Swift中ARC的教程,我很想知道为什么在操场上创建课程时可选择允许但不是隐式可选项?

我到目前为止的游乐场代码是:

class User {
    var name: String
    init(name: String) {
        self.name = name
        print("User \(name) is initialized")
    }
    deinit {
        print("User \(name) is being deallocated")
    }
}

class Phone {
    let model: String
    var owner: User?
    init(model: String) {
        self.model = model
        print("Phone \(model) is initialized")
    }
    deinit {
        print("Phone \(model) is being deallocated")
    }
}

do {
    let user1 = User(name: "John")
}
let user2 = User.init(name: "Berry")

在Phone类中,如果我将所有者变量更改为带有感叹号的隐式可选项,则操场不会抛出错误但是如果我删除问号或不使其成为可选项,则会收到错误

如果未设置应用程序,隐式可选项是否会强制应用程序崩溃?

感谢任何帮助,以便深入了解为什么隐式选项是可以的。

1 个答案:

答案 0 :(得分:5)

隐式可选仍然是可选的,因此它可以是<StackPanel Orientation="Vertical"> <local:ReusableControl x:Name="Config1" Header="Config 1"/> <local:ReusableControl x:Name="Config2" Header="Config 2"/> <local:ReusableControl x:Name="Config3" Header="Config 3"/> </StackPanel> ,并且不需要在初始化时设置。但是,如果在无效时无条件地访问它,你仍会得到例外

如果您的nil课程是:

Phone

你说

class Phone {
    let model: String
    var owner: User!
    init(model: String) {
        self.model = model
        print("Phone \(model) is initialized")
    }
    deinit {
        print("Phone \(model) is being deallocated")
    }
}

然后你会在第二行得到一个例外,因为隐式解包的可选项是var aPhone = Phone(model:"iPhone7") let ownerName = aPhone.owner.name 。如果nil类型为let ownerName = aPhone.owner!.name,则该行等同于撰写owner

如果在初始化时无法分配值,则隐式展开的选项非常有用,但此后不久会分配一个值,因为它避免了连续展开变量的需要。

例如,隐式展开的选项通常用于视图控制器中的User?属性。该属性将由故事板加载过程设置,但在视图控制器对象初始化之后。由于您知道该属性在任何代码运行时都具有值,因此使用隐式解包的可选项是安全的,您可以避免不断地解包该属性。

您的示例@IBOutlet类不能很好地使用隐式解包的选项;要么是简单的可选(如你所示),要么是必需的初始化参数是适当的,这取决于手机是否可以无主。