2016-08-14 166 views
6

在示例代碼中,我看到了兩種不同風格的聲明對象。一個優於另一個的優點是什麼?這兩種聲明風格之間有什麼區別/優點

兩個被聲明爲 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) 

我目前看到的唯一的好處是,第二風格使得代碼更清晰,當你有許多obj學分。你也可以在Xcode中摺疊它們。還有其他優勢嗎?第二個版本不會在運行時「花費」更多的資源嗎? 哪個更好?

感謝

+0

我不知道這是否有所作爲,但第二種模式只在所有設置完成後纔會分配給'btn'(即不會在發生錯誤時保留'btn'半初始化) 。 – Thilo

+0

我認爲這是有用的一個情況。當你想創建一個對象時,必須在創建時更改/分配一些值,例如一個具有可選屬性的結構,init方法不能分配它。但是你同時想保持變量本身不變。 – Surely

+0

在任何情況下都不應將該按鈕聲明爲隱式解包可選。 – nhgrif

回答

3

關閉初始化(您的第二個示例)有三大優勢。

優勢一:初始化let結構。你的例子使用了一個UIButton,這是一個類 - 一個引用類型。如果我們正在初始化一個結構爲let,我們不能改變它。一旦我們將其初始化爲let聲明,我們就不能更改任何設置者,也不能調用標記爲mutating的任何方法。關閉初始化允許我們在分配到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

的差異在小例子相當瑣碎,但可能會在更大,更復雜的軟件更顯著。

在第一個示例中,btn的狀態暫時無效 - 直到完成所有屬性分配爲止。在第二個示例中,該按鈕在分配給btn時完全構建。另外,第二個代碼實際上是一個工廠方法,可以將其分離爲一個單獨的類並進行參數化。如果正在創建許多類似的按鈕,這很有用。

將構建按鈕和其他控件的職責分離爲專業類是爲了減少iOS應用程序中視圖控制器的大小和複雜性而邁出的一步。