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

相关文章
相关标签/搜索