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

Cos*_*ows 0 optional automatic-ref-counting swift

我正在关注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")
Run Code Online (Sandbox Code Playgroud)

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

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

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

Pau*_*w11 5

隐式可选仍然是可选的,因此它可以是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")
    }
}
Run Code Online (Sandbox Code Playgroud)

而你说

var aPhone = Phone(model:"iPhone7")
let ownerName = aPhone.owner.name
Run Code Online (Sandbox Code Playgroud)

然后你会在第二行得到一个例外,因为隐式解包的可选项是nil.let ownerName = aPhone.owner!.name如果owner属于类型,该行相当于写作User?.

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

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

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

  • 谢谢.修正了. (2认同)