在Swift

时间:2017-11-12 02:21:08

标签: ios swift uiview

要以编程方式创建UIView,我可以通过两种不同的方式完成此操作。但是,我不了解每种方法的优点和缺点,哪种方法更好。

这两种方法有什么不同? ()!的做法有何不同?

任何提示都将非常感激。感谢。

代码

// Create UIView method 1

var myView1 = UIView()


// Create UIView method 2

var myView2: UIView!

2 个答案:

答案 0 :(得分:4)

第二种方法不创建UIView,它只是声明一个可以保存对UIView的引用的属性。你已经通过!将它声明为一个隐式解包的可选项,这意味着编译器并没有抱怨你没有初始化它,但是你仍然需要在某处初始化它,否则你会得到它访问它时的运行时异常。

您真正要问的是两种稍微不同的方式来声明一个可以保存对UIView的引用的属性。

Swift要求所有属性都使用值初始化或通过?声明为可选属性。 !是一个特殊情况,其中一个可选项是隐式解包;该属性仍然是一个可选类型,因此它不需要初始化,但是您告诉Swift您将初始化它,因此您在使用它时不必打开它。

例如,当从故事板加载视图控制器时,将初始化@IBOutlet UIView属性,因此您可以确信它将具有值(或者某些内容配置错误,您将得到崩溃),但该值不是由初始化程序提供的,因此该属性需要是可选的。

将属性声明为隐式解包的可选项使编译器感到高兴,即使它无法查看属性的初始化位置,也使您无需在每次引用属性时有条件地解包该属性。

您的问题是询问以编程方式创建UIView,因此您使用的方法可能取决于您希望如何创建视图。

如果您只想要一个UIView并且稍后要添加约束,可以使用:

 var myView = UIView()

 override func viewDidLoad() {
    super.viewDidLoad()
    self.myView.backgroundColor = .green
    self.myView.translatesAutoResizingMaskIntoConstraints = false
    //  Set up constraints
 }

但是,如果您想根据超级视图的框架设置视图,可以执行以下操作:

 var myView: UIView!

 override func viewDidLayoutSubviews() {
     super.viewDidLayoutSubviews()

     if self.myView == nil {
         self.myView = UIView(frame:self.view.frame)
         self.myView.backgroundColor = .green
         ...
     }
 }

一般情况下,最好避免使用明确展开的选项并强行展开,除非你确定它会有值。

答案 1 :(得分:1)

方法1 var myView1 = UIView()总是更好,因为第二种方法需要强制解包一个可选项,如果在加载视图期间它没有找到UIView,它可能会导致崩溃。除非你在故事板中创建你的视图,然后在你的视图控制器中将它们连接到Swift语言的类型安全的基本规则和避免令人不快的意外的规则,否则不建议强行解开UIView的选项。作为一个基本规则,如果通过做一些你事先知道的事情,它有可能在某些情况下崩溃,然后避免它,因为墨菲定律必然适用(无论什么可能出错都会出错,在最不合适的时候也是如此。)这是如果你通过斯威夫特文学的原因几乎每个人都要求你避免强行打开选项。