Swift 3必看:foundation中数据引用类型改为值类型

来源:互联网 发布:淘宝上货软件哪个好用 编辑:程序博客网 时间:2024/06/07 07:17

来源:没故事的卓同学

链接:http://www.jianshu.com/p/70684b2e0c15


注重安全的swift中变量声明时要表明是否可变,不变用let,可变用var。然而由于swift设计之初就要考虑兼容OC的这个历史包袱,很多类型都沿用了OC的类型。只有几个基础类型重写声明成了值类型(struct),比如:String,Array。


引用类型的let和值类型的let在逻辑上有着根本的不同。值类型的不可变就如字面意义,数据不能被更改;而引用类型的不可变只要保证指向的实例不变就可以了,实例本身的属性是可以改变的。


一些原有的OC的foundation表示数据的引用类型在swift的行为就和期待的不同了,比如:


letdate = NSDate()

date.addingTimeInterval(1000)


这样的写法是可以编译通过的。然而确和我们期望的结果不同。我们声明了一个不可变的日期,然而在 addingTimeInterval后日期已经被改变了。


所以在3.0中把原有的很多表示数据的引用类型在增加了对应的值类型。

更改的如下:


VALUE TYPECLASS TYPEAffineTransformNSAffineTransformCharacterSetNSCharacterSet, NSMutableCharacterSetDateNSDateDateComponentsNSDateComponentsDataNSData, NSMutableDataIndexSetNSIndexSet, NSMutableIndexSetIndexPathNSIndexPathNotificationNSNotificationPersonNameComponentsNSPersonNameComponentsURLNSURLURLComponentsNSURLComponentsURLQueryItemNSURLQueryItemUUIDNSUUID


在swift中相关的api返回类型也做了对应的更改。比如常见的 cellForRow方法:


func cellForRow(atindexPath:IndexPath) -> UITableViewCell?


原来的参数类型是NSIndexPath,现在则改为了IndexPath。


和原来的OC的类型映射和原来的逻辑一样,类型转换直接使用 as


letocString = NSString(string:"xxx")

letswiftString:String = ocStringasString

 

letswiftIndex = IndexPath(row:1,section:1)

letocIndex = swiftIndexasNSIndexPath


需要强调的是,两者之间的转换是有成本的。swift中并没有真正完全的实现一套数据存储逻辑。只是内部保存了对oc对象的引用,使得swift api访问时行为逻辑和值类型一致,包括copy on write。


如下图所示,当执行 var otherData = data后,其实指向的是同一个引用类型的实例。



欢迎关注我的微博:@没故事的卓同学


相关链接:


SE0069-Mutability and Foundation Value Types

http://t.cn/RqOQkDE

0 0