【问题标题】:Why isn't a implicit optional required in a class's init method?为什么类的 init 方法不需要隐式可选?
【发布时间】:2017-05-30 22:06:45
【问题描述】:

我正在关注 Ray Wenderlich 网站上关于 Swift 中的 ARC 的教程,我很想知道为什么在 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 类中,如果我将 owner 变量更改为带有感叹号的隐式可选项,则 Playground 不会引发错误,但是如果我删除问号或不使其成为可选项,则会收到错误消息.

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

感谢任何帮助,以明确理解为什么隐式可选是可以的。

【问题讨论】:

    标签: swift automatic-ref-counting optional


    【解决方案1】:

    隐含的可选项仍然是可选项,所以它可以是nil,并且不需要在初始化的时候设置。但是,如果您在它为 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。如果owner 的类型为User?,则该行相当于编写let ownerName = aPhone.owner!.name

    隐式解包选项在初始化时无法分配值的情况下非常有用,但此后不久将分配一个值,因为它避免了不断解包变量的需要。

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

    您的示例Phone 类不能很好地使用隐式展开的选项;一个简单的可选参数(如你所展示的)或一个必需的初始化参数都是合适的,这取决于手机是否可以是无主的。

    【讨论】:

    • 在您的示例中,let owner = aPhone.owner 不应导致异常。它应该导致所有者具有类型 String? 和一个 nil 值。取消引用所有者将导致异常。将最后一行更改为let owner = aPhone.owner.name 将导致异常。
    • 谢谢。解决了这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多