WWDC 学习笔记 —— 值类型在 Swift 中的应用

WWDC 2015 - Session 414 - iOS, OS X, watchOS

本文核心基于 WWDC 主题演讲内容,结合我自己的一些想法,大家可以当成翻译看。

WWDC 2015

Swift 的变量类型有两种,一种是值类型,另外一种则是引用类型。那么怎么区分一个类型是值类型还是引用类型呢?其实很简单,用 struct 声明的为值类型,用 class 声明的为引用类型。下面我们用一个例子来演示一下如何合理使用值类型。

这个例子很简单,还是画板应用,我们需要一个类型来表示一个图形,这个类型包含颜色和路径。我们用 struct 来声明这个类型,这样图形将会十分容易被拷贝。Undo Stack 需要保存各个时期的图形状态,如果用引用类型,可想而知,历史图形的属性将会被修改。

代码如下:


Figure. 1

先不要理会那个 mutablePath,我们先尝试直接修改 path 属性,看看会有什么效果。

测试用例如下:


Figure. 2

显然,rect2 拷贝了 rect1 的数据,所以修改 rect2color 属性并不会影响到 rect1,然后我们看看效果:

Figure. 3

诶?怎么只有一个三角形,rect1 那个矩形呢?

问题其实就出现在 path 上。rect2 虽然复制了 rect1,但是只是浅复制,也就是把 colorpath 的引用复制了一份,由于我们对于 rect2color 属性是直接赋值修改,所以内存中实际的操作如下:

Figure. 4

然而对于 path 的修改,我们通过引用类型直接访问了内存中唯一的 UIBezierPath 对象,所以两者的 path 就都被修改了。

那应该怎么做呢?WWDC 中提到的方法是 Copy-on-wirte,也就是说需要修改值类型中的某个引用类型时,先将其复制一份,再进行修改。在 Swift 中我们就可以这么做:

Figure. 5

通过属性访问器,在外部访问这个属性时先将原来的属性复制一份,然后返回复制后的属性,这样我们的修改就相互隔离、互不干扰了。最后修改后的代码就是这样了:
Figure. 6

看,两个图形都绘制出来了吧。

总结本 Session,着重讲的就是这个 Copy-on-write 模式,另外 WWDC 中还指出 PhotoShop 也采用了这种模式:

WWDC Keynote

它足够高效、方便。

你可能感兴趣的:(WWDC 学习笔记 —— 值类型在 Swift 中的应用)