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

时间:2016-08-14 10:18:42

标签: ios swift

在示例代码中,我看到了两种不同样式的声明对象。一个优于另一个的优势是什么?

两者都被声明为 var btn: UIButton!

风格1:

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

样式2:

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

我目前看到的唯一优势是,当你有很多对象时,第二种风格使代码更清晰。你也可以在Xcode中折叠它们。还有其他优势吗?不是第二个版本"成本"运行时有更多资源? 哪个更好?

由于

2 个答案:

答案 0 :(得分:3)

闭包初始化(你的第二个例子)有三大优点。

优势一:初始化let结构。您的示例使用UIButton,它是一个类 - 引用类型。如果我们将结构初始化为let,我们就不能改变它。我们无法更改其任何设置者,也不能在将其初始化为mutating声明后调用标记为let的任何方法。闭包初始化允许我们在分配到let - 声明的变量之前进行此设置。

优势二:范围。我们初始化的闭包有自己的范围。它可以从封闭范围中捕获变量,但在范围内声明的变量在其外部不可用。这意味着我们没有变量名称的冲突。这也意味着ARC可以在初始化完成时进行一些清理。

优势三:类/结构成员变量的内联初始化。我列出的前两个优点并不总是必要的,你通常可以解决它们。但是如果没有关闭初始化,如果你想在声明它的位置初始化你的按钮,你会遇到这样的事情:

class MyViewController: UIViewController {

    var button = UIButton()

    override func viewDidLoad() {
        super.viewDidLoad()

        // TODO: Set up button's properties

        view.addSubview(button)
    }
}

但是通过闭包初始化,我们可以在声明点设置所有设置。

class MyViewController: UIViewController {

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

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(button)
    }
}

答案 1 :(得分:1)

这些差异在小例子中相当微不足道,但在更大,更复杂的软件中可能更为重要。

在第一个示例中,WARNING:root:Unable to find `/pages/{attach}images/blog/profile.jpg` or variations. 的状态暂时无效 - 直到所有属性分配完成。在第二个示例中,按钮在分配给btn时完全构建。此外,第二个代码实际上是一个工厂方法,可以分成单独的类并进行参数化。如果正在创建许多类似的按钮,则很有用。

将构建按钮和其他控件的职责分离到专业类是朝着减少iOS应用程序中视图控制器的大小和复杂性迈出的重要一步。