Note on copy-on-write
Value types - Reference types
- Value types, where each instance keeps a unique copy of its data, usually defined as a struct, enum, or tuple.
- Reference types, where instances share a single copy of the data, and the type is usually defined as a class.
CoW - The value will be copied only upon mutation, and even then, only if it has more than one reference to it
- Suppose we have 2 variables that reference to the same data.
- DELAY the copy operation until they get a change.
- Modify second variable, it will be copied and change so that only second variable is changed, first isn’t.
- Not all value types have this behavior, have to implement it ourselves.
1func address(_ object: UnsafeRawPointer) -> String {
2 let address = Int(bitPattern: object)
3 return NSString(format: "%p", address) as String
4}
5
6struct Machine {
7 var name: String
8}
9
10var a1 = Machine(name: "Refridge")
11var a2 = a1
12
13print(address(&a1)) // 0x10525f2d0
14print(address(&a2)) // 0x10525f2e0
Print DIFFERENT addresses!
Implement CoW
1struct Machine {
2 private final class MachineWrapper {
3 var name: String
4 init(_ name: String) {
5 self.name = name
6 }
7 }
8
9 private var data: MachineWrapper
10
11 var name: String {
12 get { data.name }
13 set {
14 if !isKnownUniquelyReferenced(&data){
15 self.data = MachineWrapper(newValue)
16 print("Copied!!!")
17 } else {
18 self.data.name = newValue
19 }
20 }
21 }
22
23 init(name: String) {
24 data = MachineWrapper(name)
25 }
26}
Usage:
1var a1 = Machine(name: "Refridge")
2var a2 = a1
3
4a1.name = "Washing Machine"
Alright,
- Machine is struct, so when assigning it to another variable, value is copied!
- But the instance
data
inside is** a class**, so it is still SHARED by 2 copies UNTIL we modify thename
ofa1
More: