Swift 3必看:foundation中數據引用類型改成值類型

注重安全的swift中變量聲明時要代表是否可變,不變用let,可變用var。然而因爲swift設計之初就要考慮兼容OC的這個歷史包袱,不少類型都沿用了OC的類型。只有幾個基礎類型重寫聲明成了值類型(struct),好比:String,Arraygit

引用類型的let和值類型的let在邏輯上有着根本的不一樣。值類型的不可變就如字面意義,數據不能被更改;而引用類型的不可變只要保證指向的實例不變就能夠了,實例自己的屬性是能夠改變的。github

一些原有的OC的foundation表示數據的引用類型在swift的行爲就和期待的不一樣了,好比:swift

let date = NSDate()
date.addingTimeInterval(1000)複製代碼

這樣的寫法是能夠編譯經過的。然而確和咱們指望的結果不一樣。咱們聲明瞭一個不可變的日期,然而在 addingTimeInterval 後日期已經被改變了。api

因此在3.0中把原有的不少表示數據的引用類型在增長了對應的值類型。 更改的以下:安全

Value Type Class Type
AffineTransform NSAffineTransform
CharacterSet NSCharacterSet, NSMutableCharacterSet
Date NSDate
DateComponents NSDateComponents
Data NSData, NSMutableData
IndexSet NSIndexSet, NSMutableIndexSet
IndexPath NSIndexPath
Notification NSNotification
PersonNameComponents NSPersonNameComponents
URL NSURL
URLComponents NSURLComponents
URLQueryItem NSURLQueryItem
UUID NSUUID

在swift中相關的api返回類型也作了對應的更改。好比常見的 cellForRow 方法:app

func cellForRow(at indexPath: IndexPath) -> UITableViewCell?複製代碼

原來的參數類型是NSIndexPath,如今則改成了IndexPath。spa

和原來的OC的類型映射和原來的邏輯同樣,類型轉換直接使用 as 設計

let ocString = NSString(string: "xxx")
let swiftString: String = ocString as String

let swiftIndex = IndexPath(row: 1, section: 1)
let ocIndex = swiftIndex as NSIndexPath複製代碼

須要強調的是,二者之間的轉換是有成本的。swift中並無真正徹底的實現一套數據存儲邏輯。只是內部保存了對oc對象的引用,使得swift api訪問時行爲邏輯和值類型一致,包括copy on write。3d

以下圖所示,當執行 var otherData = data 後,其實指向的是同一個引用類型的實例。code

歡迎關注個人微博:@沒故事的卓同窗

相關連接: SE0069-Mutability and Foundation Value Types

相關文章
相關標籤/搜索