初始化中隐式解包选项 - Swift [英] Implicitly Unwrapped Optionals in Initialization - Swift

查看:169
本文介绍了初始化中隐式解包选项 - Swift的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(p)在编写新的快捷课程时,当(而不是)使用隐式解开的可选项而不是纯粹的可选项时,我仍然不能100%舒适。据我所知,如果你从来没有希望它的值为零,那么将它们指定为隐式解开(和可选)就可以了。如果它是零,这是一个特殊事件,应该导致运行时错误。



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

  class SignInFieldView:UIView {

var emailField:UITextField!
var passField:UITextField !;

必需init(coder aDecoder:NSCoder){
super.init(coder:aDecoder);
commonInit();
}

方便覆盖初始化(框架:CGRect){
self.init(frame:frame);
commonInit();
}

func commonInit(){
layoutEmail();
layoutPass();
}

// MARK:布局文本字段

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)的状态。我省略了这个额外的代码来保持这个例子的清洁。



对于初始化成员使用隐式解开的可选选项是否正确有效地使用?

解决方案

我会远离隐含展开的可选项,除非有一个很好的理由使用它们。在可能的情况下使用非可选项,否则可选。如果使用不正确,则会非常危险,因为它们绕过编译器检查并生成运行时异常。



不详尽的使用隐式解包的情况列表:




  • 当一个API返回一个隐式解开的

  • 来解决类实例之间的强参考循环问题

  • 当你有一个类(结构)属性(设计)永远不会是零,但不能在初始化程序中设置



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



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




  • 因为它很酷

  • 因为它可以保存按键当您不是100%确定是否使用键盘




在具体的情况下,虽然属性在初始化程序中实例化,但它们依赖于超类初始化,因此将其声明为隐式解包是有意义的。


When writing a new swift class, I'm still not 100% comfortable when (not) to use implicitly unwrapped optionals as opposed to just plain optionals. As far as I can tell, it should be ok to assign something as implicitly unwrapped (and optional) if you never expect it's value to be nil. If it is nil, it's an exceptional event and should cause a runtime error.

Take, for example, this simple sign-in view that contains two textfield member variables:

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);
}
}

In the above class, both emailField and passField are classified as implicitly unwrapped optionals because I never expect them to be nil throughout the life of their superview. I don't assign them as constants because I want their initialization to be dependent on the state of the superview (frame / bounds / etc). I left out that extra code to keep this example clean.

Is using implicitly unwrapped optionals for members of initialization a proper and valid use?

解决方案

I'd stay away from implicitly unwrapped optionals unless there is a good reason to use them. Use non optional, when possible, otherwise optionals. Implicitly unwrapped are very dangerous if improperly used because they bypass the compiler check and generate runtime exceptions.

Non exhaustive list of cases when to use implicitly unwrapped:

  • when there's an API returning an implicitly unwrapped
  • to solve the Strong Reference Cycles Between Class Instances problem
  • when you have a class/struct property that (by design) will never be nil, but it cannot be set in the initializer

A typical case of the latter usage is in a UIViewController, when a property is initialized in the viewDidLoad method rather than in an initializer - it makes sense to use an implicitly unwrapped.

Do not use implicitly unwrapped in this cases:

  • because it's cool
  • because it lets you save a key press on the keyboard
  • when you are not 100% sure whether to use it or not

In your specific case, although the properties are instantiated in the initializator, they depend from the superclass initialization, so it makes sense to declare them as implicitly unwrapped.

这篇关于初始化中隐式解包选项 - Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆