快速复制多行_快速复制

快速复制多行

In most programming languages, variables are either categorized as value types or reference types.

在大多数编程语言中,变量要么归类为值类型,要么归类为引用类型。

A value type keeps a unique copy of its data. This means if you assign it to another variable a new copy of the data is created and both variables work independently.

值类型保留其数据的唯一副本。 这意味着,如果将其分配给另一个变量,则会创建数据的新副本,并且两个变量都将独立工作。

Reference types, on the other hand, store a pointer to the memory address of the data. This means every new instance assigned to that reference will point to the same address thereby share their copy of data.

另一方面,引用类型存储指向数据存储地址的指针。 这意味着分配给该引用的每个新实例都将指向相同的地址,从而共享其数据副本。

While the above definitions make it seem fairly straightforward, Swift’s value types and semantics are quite different from other languages.

尽管上面的定义看起来很简单,但是Swift的值类型和语义与其他语言完全不同。

To demonstrate that, let’s look at a JavaScript example first:

为了说明这一点,让我们首先来看一个JavaScript示例:

var ar1 = ['a', 'b', 'c'];
var ar2 = ar1; // assign ar1 to ar2
ar2[0] = 1; // modify ar2
console.log(ar1); // [1, "b", "c"]
console.log(ar2); // [1, "b", "c"]

As we modified an element of ar2 it changed ar1 as well. This is because Arrays are reference types in JavaScript. On the contrary, with primitive types like numbers, mutating one variable won’t affect the other.

当我们修改ar2的元素时,它也更改了ar1 。 这是因为数组是JavaScript中的引用类型。 相反,对于像数字这样的原始类型,对一个变量进行突变不会影响另一个变量。

Coming back to Swift, arrays, dictionaries, sets, and strings are actually value types and not reference types. Also, struct, enum and tuples fall under value types as well leaving only classes and functions as reference types.

回到Swift,数组,字典,集合和字符串实际上是值类型,而不是引用类型。 同样, structenumtuples属于值类型,并且仅保留类和函数作为引用类型。

Swift中的集合是值类型 (Collections in Swift are Value Types)

One might wonder why Swift’s language design implementation team had picked collections as value types since most languages use them as reference types.

有人可能会问为什么Swift的语言设计实现团队会选择集合作为值类型,因为大多数语言都将它们用作引用类型。

The primary reason behind using collections as value types is that it lets you reason the code easily — no other part of your codebase can change it. This is helpful in multi-threaded environments where another thread could alter the instance if it wasn’t unique.

将集合用作值类型的主要原因在于,它使您可以轻松地推理代码-代码库的其他部分都无法更改它。 这在多线程环境中很有用,如果另一个线程不是唯一的,则另一个线程可能会更改该实例。

Now, imagine a large array that you’re looking to pass by value to a function. Clearly, copying the whole array isn’t a memory-efficient way of doing things. Gladly, Swift has its own copy-on-write mechanism. Let’s see what it is.

现在,想象一个大型数组,您希望通过值将其传递给函数。 显然,复制整个数组并不是一种节省内存的处理方式。 很高兴,Swift有自己的写时复制机制。 让我们看看它是什么。

写时复制机制 (Copy-on-Write Mechanism)

Copy-on-Write is a computing technique available in the Swift standard library for value types such as collections and structs. Essentially, it defers the copying of collections and structures until when it’s actually needed.

写时复制是Swift标准库中可用的一种计算技术,用于诸如collection和structs值类型。 本质上,它将延迟对集合和结构的复制,直到真正需要它时为止。

This means that once you assign a value type instance to a new variable or pass it in the function, the memory storage is shared until you modify any of the instances. The following illustration explains this:

这意味着,一旦您将值类型实例分配给新变量或将其传递给函数,便会共享内存存储,直到您修改任何实例为止。 下图说明了这一点:

Image for post
By author
按作者

The above diagram illustrates that value types assignment has deep copy semantics. This implies that the value types are backed by reference types until modification or mutation happens.

上图说明了值类型分配具有深层复制语义。 这意味着值类型由引用类型支持,直到发生修改或突变。

Let’s validate this fact by running a piece of code in the Xcode playground and tracking the address of the instances:

让我们通过在Xcode游乐场中运行一段代码并跟踪实例的地址来验证这一事实:

func address(o: UnsafeRawPointer) -> NSString {
let addr = Int(bitPattern: o)
return NSString(format: "%p", addr)
}struct Point {
var p: Int
}var pointA = [Point(p: 25), Point(p: 20)]
//1
var pointB = pointA//2
pointA[0].p = 10

During the assignment and modification of struct instances, two things are happening under the hood:

在结构实例的分配和修改过程中,发生了两件事:

  1. When pointB is assigned to pointA they both contain the same address.

    pointB分配给pointB pointA它们都包含相同的地址。

  2. Once pointA is modified, a deep copy of the old pointA takes place and pointB now points to a different address.

    一旦pointA被修改,旧的深层副本pointA发生和pointB现在指向不同的地址。

The following screengrab from the playground prints the address changes during the copy-on-write process.

操场上的以下屏幕截图显示了写时复制过程中的地址更改。

Image for post

In another scenario, if you add a reference type property inside a value type, those references won’t be copied like value types. Instead, the same reference would be used.

在另一种情况下,如果在值类型内添加引用类型属性,则这些引用将不会像值类型那样被复制。 相反,将使用相同的参考。

The following screengrab showcases an example when a class instance is defined as a property of a struct.

以下屏幕截图展示了将类实例定义为struct的属性时的示例。

Image for post

Notice how despite the copy-on-write, the address of the class instance doesn’t change across the two array of structs.

请注意,尽管有写时复制功能,但类实例的地址在两个结构数组之间如何保持不变。

总结思想 (Closing Thoughts)

In a nutshell, a value type contains data and a reference type contains the location in memory where the data resides.

简而言之,值类型包含数据,引用类型包含数据在内存中的位置。

Value types are stored in stack memory(unless it’s a part of a class instance) and reference types are stored in heap memory. Typically, you should use value types when copies of data can have independent states. Value types with inner reference properties should be avoided as they violate value semantics and introduce an additional reference count overhead.

值类型存储在堆栈内存中(除非它是类实例的一部分),引用类型存储在堆内存中。 通常,当数据副本可以具有独立状态时,应使用值类型。 具有内部引用属性的值类型应避免使用,因为它们违反了值语义,并引入了额外的引用计数开销。

Copy-on-Write is Swift’s smart way to optimize the copying of value types. This helps boost the performance of our applications where we’re relying on structs for populating the data.

写时复制是Swift优化值类型复制的明智方法。 这有助于提高我们依赖于结构填充数据的应用程序的性能。

That’s it for this one. Thanks for reading.

这就是它了。 谢谢阅读。

翻译自: https://levelup.gitconnected.com/copy-on-write-in-swift-1faf488e2072

快速复制多行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值