简体   繁体   English

这两种声明样式之间有什么区别/优点

[英]What is the difference/advantages between these two declaration styles

In sample code I have seen two different styles of declaring objects. 在示例代码中,我看到了两种不同的声明对象样式。 What is the advantage of one over the other? 一个相对于另一个的优势是什么?

Both are declared as var btn: UIButton! 两者都声明为var btn: UIButton!

Style 1: 样式1:

btn = UIButton()
btn.translatesAutoresizingMaskIntoConstraints = false
btn.layer.borderColor = UIColor.blue.cgColor
btn.layer.borderWidth = 1
...
self.view.addSubview(btn)

Style 2: 样式2:

btn = {
   let b = UIButton()
   b.translatesAutoresizingMaskIntoConstraints = false
   b.layer.borderColor = UIColor.blue.cgColor
   b.layer.borderWidth = 1
   ...
   return b
}()
self.view.addSubview(btn)

The only advantage I currently see is that the second style makes code more legible when you have many objects. 我目前看到的唯一好处是,当您有许多对象时,第二种样式使代码更易读。 You can also collapse them in Xcode. 您也可以在Xcode中折叠它们。 Is there any other advantage? 还有其他优势吗? Doesn't the second version "cost" more resources at runtime? 第二个版本是否在运行时“消耗”了更多资源? Which is preferable? 哪个更好?

Thanks 谢谢

Closure initialization (your second example) has three big advantages. 闭包初始化(第二个示例)具有三大优势。

Advantage one: Initializing let structs. 优势一:初始化let结构。 Your example uses a UIButton , which is a class--a reference type. 您的示例使用UIButton ,它是一个类-引用类型。 If we are initializing a struct into a let , we can not mutate it. 如果我们将一个结构初始化为let ,则不能对其进行突变。 We cannot change any of its setters, nor can we call any methods marked as mutating once we initialize it into a let declaration. 一旦将其初始化为let声明,我们就无法更改其设置器,也不能调用任何标记为mutating方法。 The closure initialization allows us to do this set up before assigning into the let -declared variable. 关闭初始化允许我们在分配给let -declared变量之前进行此设置。

Advantage two: Scope. 优势二:范围。 The closure we initialize with gets its own scope. 我们初始化的闭包有自己的作用域。 It can capture variables from the enclosing scope, but variables declared within the scope are not available outside it. 它可以从封闭范围中捕获变量,但是在该范围内声明的变量在其外部不可用。 This means we don't have collisions on variable names. 这意味着我们在变量名上没有冲突。 It also means that ARC could do some clean-up as our initialization completes. 这也意味着ARC可以在初始化完成后进行一些清理。

Advantage three: In-line initialization of class/struct member variables. 优势三:在线初始化类/结构成员变量。 The first two advantages I listed aren't always necessary and you can usually work around them. 我列出的前两个优点并非总是必要的,您通常可以解决它们。 But without closure initialization, if you wanted to initialize your button at the point it is declared, you are stuck with something like this: 但是如果没有闭包初始化,如果您想在声明按钮的那一刻初始化按钮,那么您将遇到以下问题:

class MyViewController: UIViewController {

    var button = UIButton()

    override func viewDidLoad() {
        super.viewDidLoad()

        // TODO: Set up button's properties

        view.addSubview(button)
    }
}

But with closure initialization, we can set those all set up at the point of declaration. 但是,通过闭包初始化,我们可以在声明时设置所有设置。

class MyViewController: UIViewController {

    var button: UIButton = {
        let button = UIButton()
        // TODO: Set up button
        return button
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(button)
    }
}

The differences are fairly trivial in small examples but may be more significant in larger, more complex software. 在较小的示例中,差异很小,但是在较大,更复杂的软件中,差异可能更大。

In the first example, the state of btn is temporarily invalid - until all of the property assignments are complete. 在第一个示例中, btn的状态暂时无效-直到完成所有属性分配。 In the second example, the button is completely built when assigned to btn . 在第二个示例中,当将按钮分配给btn时,按钮将完全构建。 In addition, the code in the second is, in effect, a factory method that could be separated out into a separate class and parameterised. 此外,第二个代码实际上是一种工厂方法,可以将其分离为单独的类并进行参数化。 Useful if a lot of similar buttons are being created. 如果正在创建许多类似的按钮,则很有用。

Separating the responsibility for building buttons and other controls into specialist classes is an excellent step towards reducing the size and complexity of view controllers in iOS apps. 将构建按钮和其他控件的责任划分为专家类,是朝着减少iOS应用程序中视图控制器的大小和复杂性迈出的出色一步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM