Swift程式設計思想,Struct(結構體)
目錄
參考:https://www.jianshu.com/p/c2e1cab05ab9
常看見 Swift 的新手嘗試著把它們的 ObjC 程式碼翻譯成 Swift。但是開始用 Swift 寫程式碼的時候最難的事情並不是語法,而是思維方式的轉變,去用那些 ObjC 裡並沒有的 Swift 新概念。
1. Struct的概述
struct 是 值型別 而 class 是 引用型別
值型別的變數直接包含他們的資料,而引用型別的變數儲存對他們的資料引用,因此後者稱為物件,因此對一個變數操作可能影響另一個變數所引用的物件。對於值型別都有他們自己的資料副本,因此對一個變數操作不可能影響另一個變數
相對於OC中的Struct,Swift中的Struct變得更加強大,不僅有成員變數,還多了成員方法,使它更加接近於一個類.
2. Struct的相對於Class的優缺點
優點
-
安全性
因為 Struct 是用值型別傳遞的,它們沒有引用計數。不需要擔心資料被其他持有者改變的現象 -
記憶體
由於沒有引用數,所以不會因為迴圈引用導致記憶體洩漏。 -
速度
值型別通常來說是以棧的形式分配的,而不是用堆。因此他們比 Class 要快很多,真的很多!
在 StackOverflow 給 struct 和 class 進行相同操作的表現做了基準測試, Struct 比 Class 要快九百倍。(注:在 2016-05-07 的測試中,Struct 的速度為 Class 的三千七百萬倍,詳見 StackOverflow -
拷貝
因為是值型別,不需要想引用型別一樣考慮深拷貝淺拷貝,值型別的拷貝則非常輕鬆! -
執行緒安全
值型別是自動執行緒安全的。無論你從哪個執行緒去訪問你的 Struct ,都非常簡單。 -
構造器
struct SListItem { var icon: String = "" var title: String = "" var url: String = "" } func start() { //相對於class struct會自動生成一個構造器 let slist:SListItem = SListItem(icon: "", title: "", url: "") let clist:CListItem = CListItem() } class CListItem{ var icon: String = "" var title: String = "" var url: String = "" }
缺點
- 混合開發
在混合開發中,Swift的Struct不能夠被OC呼叫,因為要在 Objective-C 裡呼叫 Swift 程式碼的話,物件需要繼承於 NSObject。 - 繼承
作為面向物件的三大特徵之一,繼承讓開發者節省了大部分重複性的程式碼
但是Struct不支援繼承,不過好在Struct支援協議,這也體現了Swift面向協議的程式設計思想 - 歸檔
Struct 不能被序列化成 NSData 物件。比如NSUserDefaults
這時候還是需要使用class的
3. 將Class轉為Swift
在我們的例子中,使用一個結構體看起來更為合適,因為它儲存了一些值,並且並不會要對它們做什麼改變(更適合拷貝而非引用)。案例中,我們把它用作一個選單欄的資料來源,一旦建立就不再對其更改,所以這也是使用結構體更為合理的一個場景。
struct ListItem {
var icon: UIImage?
var title: String
var url: NSURL
static func listItemsFromJSONData(jsonData: NSData?) -> [ListItem] {
guard let nonNilJsonData = jsonData,
let json = try? JSONSerialization.jsonObject(with: nonNilJsonData as Data, options: []),
let jsonItems = json as? Array<NSDictionary> else { return [] }
return jsonItems.flatMap { (itemDesc: NSDictionary) -> ListItem? in
guard let title = itemDesc["title"] as? String,
let urlString = itemDesc["url"] as? String,
let url = NSURL(string: urlString)
else { return nil }
let iconName = itemDesc["icon"] as? String
let icon = UIImage(named: iconName ?? "")
return ListItem(icon: icon, title: title, url: url)
}
}
}
4. Struct與ObjectMapper
在字典轉模型的過程中,我們可以使用ObjectMapper進行操作