-
Struct的概述
-
Struct相對(duì)于Class的優(yōu)缺點(diǎn)
-
將Class轉(zhuǎn)為Swift
-
Struct與ObjectMapper
常看見 Swift 的新手嘗試著把它們的 ObjC 代碼翻譯成 Swift。但是開始用 Swift 寫代碼的時(shí)候最難的事情并不是語(yǔ)法,而是思維方式的轉(zhuǎn)變,去用那些 ObjC 里并沒有的 Swift 新概念。
1. Struct的概述
struct 是 值類型 而 class 是 引用類型
值類型的變量直接包含他們的數(shù)據(jù),而引用類型的變量存儲(chǔ)對(duì)他們的數(shù)據(jù)引用,因此后者稱為對(duì)象,因此對(duì)一個(gè)變量操作可能影響另一個(gè)變量所引用的對(duì)象。對(duì)于值類型都有他們自己的數(shù)據(jù)副本,因此對(duì)一個(gè)變量操作不可能影響另一個(gè)變量
相對(duì)于OC中的Struct,Swift中的Struct變得更加強(qiáng)大,不僅有成員變量,還多了成員方法,使它更加接近于一個(gè)類.
2. Struct的相對(duì)于Class的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 安全性
因?yàn)?Struct 是用值類型傳遞的,它們沒有引用計(jì)數(shù)。不需要擔(dān)心數(shù)據(jù)被其他持有者改變的現(xiàn)象
- 內(nèi)存
由于沒有引用數(shù),所以不會(huì)因?yàn)檠h(huán)引用導(dǎo)致內(nèi)存泄漏。
- 速度
值類型通常來(lái)說是以棧的形式分配的,而不是用堆。因此他們比 Class 要快很多,真的很多!
在 [StackOverflow](http://stackoverflow.com/a/24243626/596821) 給 struct 和 class 進(jìn)行相同操作的表現(xiàn)做了基準(zhǔn)測(cè)試,Struct 比 Class 要快九百倍。(注:在 2016-05-07 的測(cè)試中,Struct 的速度為 Class 的三千七百萬(wàn)倍,詳見 [StackOverflow](http://stackoverflow.com/a/24243626/596821))
- 拷貝
因?yàn)槭侵殿愋?不需要想引用類型一樣考慮深拷貝淺拷貝,值類型的拷貝則非常輕松!
- 線程安全
值類型是自動(dòng)線程安全的。無(wú)論你從哪個(gè)線程去訪問你的 Struct ,都非常簡(jiǎn)單。
- 構(gòu)造器
struct SListItem {
var icon: String = ""
var title: String = ""
var url: String = ""
}
func start() {
//相對(duì)于class struct會(huì)自動(dòng)生成一個(gè)構(gòu)造器
let slist:SListItem = SListItem(icon: "", title: "", url: "")
let clist:CListItem = CListItem()
}
class CListItem{
var icon: String = ""
var title: String = ""
var url: String = ""
}
缺點(diǎn)
- 混合開發(fā)
在混合開發(fā)中,Swift的Struct不能夠被OC調(diào)用,因?yàn)橐?Objective-C 里調(diào)用 Swift 代碼的話,對(duì)象需要繼承于 NSObject。
- 繼承
作為面向?qū)ο蟮娜筇卣髦?繼承讓開發(fā)者節(jié)省了大部分重復(fù)性的代碼
但是Struct不支持繼承,不過好在Struct支持協(xié)議,這也體現(xiàn)了Swift面向協(xié)議的編程思想
- 歸檔
Struct 不能被序列化成 NSData 對(duì)象。比如NSUserDefaults
這時(shí)候還是需要使用class的
3. 將Class轉(zhuǎn)為Swift
在我們的例子中,使用一個(gè)結(jié)構(gòu)體看起來(lái)更為合適,因?yàn)樗4媪艘恍┲?,并且并不?huì)要對(duì)它們做什么改變(更適合拷貝而非引用)。案例中,我們把它用作一個(gè)菜單欄的數(shù)據(jù)源,一旦創(chuàng)建就不再對(duì)其更改,所以這也是使用結(jié)構(gòu)體更為合理的一個(gè)場(chǎng)景。
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
在字典轉(zhuǎn)模型的過程中,我們可以使用ObjectMapper進(jìn)行操作
文章是參考了很多國(guó)內(nèi)外的文章,加上了一些個(gè)人的觀點(diǎn)
能力甚微,只敢說拼拼湊湊而成
如有不足,請(qǐng)指教
文章參考:https://medium.com/swift-programming/swift-caveats-for-structs-as-data-models-8299d84b49dc
http://swift.gg/2015/10/20/thinking-in-swift-3/