初始化中隐式解包的选项 – Swift

在编写一个新的swift类时,我仍然不是100%舒服的时候(不)使用隐式解包的选项而不是普通的选项。 据我所知,如果您从未预期它的值为零,那么分配一些隐式展开(和可选)的东西应该没问题。 如果它是nil,则它是一个exception事件,应该导致运行时错误。

例如,这个简单的登录视图包含两个文本域成员变量:

class SignInFieldView : UIView { var emailField: UITextField!; var passField: UITextField!; required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder); commonInit(); } convenience override init(frame: CGRect) { self.init(frame: frame); commonInit(); } func commonInit() { layoutEmail(); layoutPass(); } // MARK: Layout Text Fields func layoutEmail() { let rect = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.size.width, height: (bounds.size.height * 0.5)); emailField = UITextField(frame: rect); addSubview(emailField); } func layoutPass() { let rect = CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height * 0.5), width: bounds.size.width, height: (bounds.size.height * 0.5)); passField = UITextField(frame: rect); addSubview(passField); } } 

在上面的类中,emailField和passField都被归类为隐式解包的选项,因为我从不期望它们在超级视图的整个生命周期中都是零。 我不将它们指定为常量,因为我希望它们的初始化依赖于superview的状态(frame / bounds / etc)。 我遗漏了额外的代码来保持这个例子干净。

是否使用隐式解包的选项为初始化成员正确有效地使用?

除非有充分的理由使用它们, 否则我会远离隐式解包的选项。 如果可能,请使用非可选项,否则使用其他选项。 如果使用不当,隐式展开会非常危险,因为它们会绕过编译器检查并生成运行时exception。

非详尽列表的情况何时使用隐式展开:

  • 当有一个API返回隐式解包时
  • 解决类实例之间的强引用周期问题
  • 当你有一个类/结构属性(按设计)永远不会是nil,但它不能在初始化器中设置

后一种用法的典型情况是在UIViewController ,当在viewDidLoad方法而不是初始化程序中初始化属性时 – 使用隐式展开是有意义的。

在这种情况下不要使用隐式解包:

  • 因为它很酷
  • 因为它可以让您在键盘上保存按键
  • 当你不是100%确定是否使用它

在您的特定情况下,尽管属性在初始化器中实例化,但它们依赖于超类初始化,因此将它们声明为隐式解包是有意义的。