注重安全的swift中變量聲明時要代表是否可變,不變用let
,可變用var
。然而因爲swift設計之初就要考慮兼容OC的這個歷史包袱,不少類型都沿用了OC的類型。只有幾個基礎類型重寫聲明成了值類型(struct),好比:String
,Array
。git
引用類型的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
歡迎關注個人微博:@沒故事的卓同窗