Swift arrays are value types that copy on write. If a the original array is not mutated then the “copy” points to the same memory location.
Supposed we have a class referenced by multiple threads
class Foo {
var numbers: [Int] = [1, 2, 3]
}
let foo = Foo()
If thread A “copies” numbers
var numbers = foo.numbers
and then later thread B replaces numbers
with a different array instance
foo.numbers = [4, 5, 6]
will the original numbers array ([1, 2, 3]
) be deallocated, resulting in incorrect checksum for freed object - object was probably modified after being freed
when thread B attempts to access its elements?
var numbers = foo.numbers
will always contain [1, 2, 3]
until you modify var numbers
.
let foo = Foo()
// Thread A
var numbers = foo.numbers
// Thread b
foo.numbers = [4, 5, 6]
// Thread A again - 'var numbers' still has a "reference" to [1, 2, 3]
print(numbers) // "[1, 2, 3]"
I think you're misunderstanding how structs in swift act as value types. The original [1, 2, 3]
array will not overwritten when you reassign foo.numbers
.
Say you have 10 threads all of which "copy" foo.numbers
, at this point the array's memory is not copied.
var myTheadNumbers = foo.numbers
Lets say thread 1 modifies the array
myThreadNumbers.append(4)
[1, 2, 3]
is copied to a new array which is then modified by appending 4.
Thread 1 now has it's own a single array of [1, 2, 3, 4]
while threads 2-10 are still sharing the original [1, 2, 3]
. That's what copy-on-write means for structs - you only take the performance hit for copying when you modify a struct and someone else has an old copy laying around.
Each one of those 10 threads acts like they have their own copy of [1, 2, 3]
which is the meaning of value types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With