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

Why isn't a implicit optional required in a class's init method?

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

我目前的 playground 代码是:

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 class 中,如果我将 owner 变量更改为带有感叹号的隐式可选变量,那么 playground 不会抛出错误,但是如果我删除问号或不' 将其设为可选然后我收到错误消息。

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

感谢任何帮助,以坚定地理解为什么隐式可选是好的。

隐式可选仍然是可选的,所以它可以是nil并且不需要在初始化时设置。但是,如果您在它为 nil.

时无条件访问它,您仍然会得到一个异常

如果您的 Phone class 是:

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。如果 ownerUser?.

类型,那一行相当于写 let ownerName = aPhone.owner!.name

隐式解包的可选值在初始化时无法赋值但很快就会赋值的情况下非常有用,因为它避免了不断解包变量的需要。

例如,隐式展开的可选值通常用于视图控制器中的 @IBOutlet 属性。 属性 将由故事板加载过程设置,但在初始化视图控制器对象之后。由于您知道 属性 在您的任何代码运行时都会有一个值,因此使用隐式解包的可选值是安全的,并且您不必不断地解包 属性.

您的示例 Phone class 没有很好地使用隐式解包选项;一个简单的可选(如你所展示的)或一个必需的初始化参数是合适的,这取决于电话是否可以是无主的。