内容简介:在Swift中,有两种传值方式:引用类型(Class)和值类型(Struct/Enum)。而值类型有一个copy的操作,它的意思是当你传递一个值类型的变量的时候(给一个变量赋值,或者函数中的参数传值),它会拷贝一份新的值让你进行传递。你会得到拥有相同内容的两个变量,分别指向两块内存。这样的话,在你频繁操作占用内存比较大的变量的时候就会带来严重的性能问题,Swift也意识到了这个问题,所以推出了Copy-on-Write机制,用来提升性能。下面我们来说一下什么是Copy-on-Write。当你有一个占用内存很
在Swift中,有两种传值方式:引用类型(Class)和值类型(Struct/Enum)。而值类型有一个copy的操作,它的意思是当你传递一个值类型的变量的时候(给一个变量赋值,或者函数中的参数传值),它会拷贝一份新的值让你进行传递。你会得到拥有相同内容的两个变量,分别指向两块内存。
这样的话,在你频繁操作占用内存比较大的变量的时候就会带来严重的性能问题,Swift也意识到了这个问题,所以推出了Copy-on-Write机制,用来提升性能。下面我们来说一下什么是Copy-on-Write。
什么是Copy-on-Write
当你有一个占用内存很大的一个值类型,并且不得不将它赋值给另一个变量或者当做函数的参数传递的时候,拷贝它的值是一个非常消耗内存的操作,因为你不得不拷贝它所有的东西放置在另一块内存中。
为了优化这个问题,Swift对于一些特定的值类型(集合类型:Array、Dictionary、Set)做了一些优化,在对于Array进行拷贝的时候,当传递的值进行改变的时候才会发生真正的拷贝。而对于String、Int等值类型,在赋值的时候就会发生拷贝。下面来看代码验证一下:
先看一下基本类型(Int、String等)
var num1 = 10 var num2 = num1 print(address(of: &num1)) //0x7ffee0c29828 print(address(of: &num2)) //0x7ffee0c29820 var str1 = "abc" var str2 = str1 print(address(of: &str1)) //0x7ffee0c29810 print(address(of: &str2)) //0x7ffee0c29800 //打印内存地址 func address(of object: UnsafeRawPointer) -> String { let addr = Int(bitPattern: object) return String(format: "%p", addr) } 复制代码
从上面的打印我们可以看出基本类型在进行赋值的时候就发生了拷贝操作
在看一下集合类型
var arr1 = [1,2,3,4,5] var arr2 = arr1 print(address(of: &arr1)) //0x6000023b06b0 print(address(of: &arr2)) //0x6000023b06b0 arr2[2] = 4 print(address(of: &arr1)) //0x6000023b06b0 print(address(of: &arr2)) //0x6000023b11f0 复制代码
从上面代码我们可以看出,当arr1赋值给arr2时并没有发生拷贝操作,当arr2的值改变的时候才发生了拷贝操作
Copy-on-Write是一种非常好的方式去优化值类型的拷贝,虽然对于这套底层逻辑我们不用实现,但是了解这个机制对于我们来说还是非常必要的。通过上面的代码我们看到了Copy-on-Write机制是如何发生作用的,但是知道它如何应用是不够的,我们要做到知其然并且知其所以然。所以,接下来我们看一下Swift源代码是如何实现这一机制的。
Copy-on-Write如何实现的
你可以在 OptimizationTips.rst 里发现如下代码:
final class Ref<T> { var val : T init(_ v : T) {val = v} } struct Box<T> { var ref : Ref<T> init(_ x : T) { ref = Ref(x) } var value: T { get { return ref.val } set { if (!isUniquelyReferencedNonObjC(&ref)) { ref = Ref(newValue) return } ref.val = newValue } } } 复制代码
该例子显示了如何用一个引用类型去实现一个拥有copy-on-write特性的泛型值类型T。具体逻辑就是当你进行set的时候判断是否有多个reference,如果是多个reference则进行拷贝,反之则不会。
以上所述就是小编给大家介绍的《浅谈Swift中的Copy-on-Write》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java编程思想 (第4版)
[美] Bruce Eckel / 陈昊鹏 / 机械工业出版社 / 2007-6 / 108.00元
本书赢得了全球程序员的广泛赞誉,即使是最晦涩的概念,在Bruce Eckel的文字亲和力和小而直接的编程示例面前也会化解于无形。从Java的基础语法到最高级特性(深入的面向对象概念、多线程、自动项目构建、单元测试和调试等),本书都能逐步指导你轻松掌握。 从本书获得的各项大奖以及来自世界各地的读者评论中,不难看出这是一本经典之作。本书的作者拥有多年教学经验,对C、C++以及Java语言都有独到......一起来看看 《Java编程思想 (第4版)》 这本书的介绍吧!