注重安全的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
欢迎关注个人微博:@没故事的卓同窗