別人一看到我的 Swift 代碼,立刻就會問我為什么如此頻繁的使用 extension。這是前幾天在我寫的另一篇文章中收到的評論:
我大量使用 extension 的主要目的是為了提高代碼可讀性。以下是我喜歡使用 extension 的場景,盡管 extension 並非是為這些場景設計的。
私有的輔助函數
在 Objective-C 中,我們有 .h 文件和 .m 文件。同時管理這兩個文件(以及在工程中有雙倍的文件)是一件很麻煩的事情,好在我們只要快速瀏覽 .h 文件就可以知道這個類對外暴露的 API,而內部的信息則被保存在 .m 文件中。在 Swift 中,我們只有一個文件。
為了一眼就看出一個 Swift 類的公開方法(可以被外部訪問的方法),我把內部實現都寫在一個私有的 extension 中,比如這樣:
// 這樣可以一眼看出來,這個結構體中,那些部分可以被外部調用 |
注意,在上面這個例子中,屬性字符串的計算邏輯非常復雜。如果把它寫在結構體的主體部分中,我就無法一眼看出這個結構體中哪個部分是重要的(也就是 Objective-C 中寫在 .h 文件中的代碼)。在這個例子中,使用 extension 使我的代碼結構變得更加清晰整潔。
這樣一個很長的 extension 也為日后重構代碼打下了良好的基礎。我們有可能把這段邏輯抽取到一個單獨的結構體中,尤其是當這個屬性字符串可能在別的地方被用到時。但在編程時把這段代碼放在私有的 extension 里面是一個良好的開始。
分組
我最初開始使用 extension 的真正原因是在 Swift 剛誕生時,無法使用 pragma 標記(譯注:Objective-C 中的 #pragma mark)。是的,這就是我在 Swift 剛誕生時想做的第一件事。我使用 pragma 來分割 Objective-C 代碼,所以當我開始寫 Swift 代碼時,我需要它。
所以我在 WWDC Swift 實驗室時詢問蘋果工程師如何在 Swift 中使用 pragma 標記。和我交流的那位工程師建議我使用 extension 來替代 pragma 標記。於是我就開始這么做了,並且立刻愛上了使用 extension。
盡管 pragma 標記(Swift 中的 //MARK)很好用,但我們很容易忘記給一段新的代碼加上 MARK 標記,尤其是你處在一個具有不同代碼風格的小組中時。這往往會導致若干個無關函數被放在了同一個組中,或者某個函數處於錯誤的位置。所以如果有一組函數應該寫在一起,我傾向於把他們放到一個 extension 中。
一般我會用一個 extension 存放 ViewController 或者 AppDelegate 中所有初始化 UI 的函數,比如:
private extension AppDelegate { |
或者把所有和通知相關的邏輯放到一起:
extension TodoListViewController { |
遵守協議
這是一種特殊的分組,我會把所有用來實現某個協議的方法放到一個 extension 中。在 Objective-C 中,我習慣使用 pragma 標記。不過我喜歡 extension 更加徹底的分割和更好的可讀性:
struct TodoItemViewModel { |
這種方法同樣非常適用於分割 UITableViewDataSource 和 UITableViewDelegate 的代碼:
// MARK: 表格視圖數據源 |
模型(Model)
這是一種我在使用 Objective-C 操作 Core Data 時就喜歡采用的方法。由於模型發生變化時,Xcode 會生成相應的模型,所以函數和其他的東西都是寫在 extension 或者 category 里面的。
在 Swift 中,我盡可能多的嘗試使用結構體,但我依然喜歡使用 extension 將 Model 的屬性和基於屬性的計算分割開來。這使 Model 的代碼更容易閱讀:
struct User { |
長話短說(TL;DR)
盡管這些用法可能不那么“傳統”,但 Swift 中 extension 的簡單使用,可以讓代碼質量更高,更具可讀性。
轉載自:http://swift.gg/2016/05/16/using-swift-extensions/
參考鏈接:https://www.natashatherobot.com/using-swift-extensions/