Let's say I want to write the value type properties of a class instance in one thread, while reading the same from another thread -- see example code below. What is the worst that can happen?
Obviously there are no guarantees for the internal consistency of x
at the time of reading, the read
thread might print 0, true, bar, [1, 2]
, or 1, true, foo, [1, 2]
, etc. Let's assume that's not a concern.
Are the property assignments themselves atomic? Or is it possible for the writer thread to start but not quite finish the assignment of, say, x.i = 2
, before the reader thread prints the value of x.i
? Does the answer depend on the kind of value type (Int, Bool, String, Array, etc.)?
If the assignments are atomic, where is this documented?
If they are not atomic, can this cause a crash, or the printing of a value that wasn't actually assigned (in the case of x.i
, not one of 0, 1 or 2)? Is there a way to write a test to demonstrate this?
class X {
var i: Int = 0
var b: Bool = false
var s: String = ""
var a: [Int] = []
}
func write(x: X) {
x.i = 1
x.b = true
x.s = "foo"
x.a = [1]
x.i = 2
x.b = false
x.s = "bar"
x.a = [1, 2]
}
func read(x: X) {
print(x.i)
print(x.b)
print(x.s)
print(x.a)
}
var x = X()
let queue = DispatchQueue.global()
queue.async {
write(x: x)
}
queue.async {
read(x: x)
}
Edit: Reflecting on the comments, I wanted to add that I am primarily interested in Bool
and String
values, and the iOS platform(s) -- and I ran a test with a few million read/write cycles on several devices without triggering any kind of error. So even knowing that Swift doesn't provide any guarantees, I still wonder if one could reasonably rely on the platform itself to do so. I changed the title to reflect this.