让我们说我想在一个线程中编写类实例的值类型属性,同时从另一个线程读取它 - 请参阅下面的示例代码。可能发生的最坏情况是什么?
显然,在阅读时无法保证x
的内部一致性,read
主题可能会打印0, true, bar, [1, 2]
或1, true, foo, [1, 2]
,等等。 39; s假设不是一个问题。
属性赋值本身是原子的吗?或者,在读者线程打印x.i = 2
的值之前,编写器线程是否可以启动但不完全完成x.i
的分配?答案取决于值类型的类型(Int,Bool,String,Array等)吗?
如果作业是原子的,那么会记录在哪里?
如果它们不是原子的,是否会导致崩溃,或打印未实际分配的值(在x.i
的情况下,而不是0,1或2中的一个)?有没有办法写一个测试来证明这一点?
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)
}
修改:反思评论,我想补充一点,我主要对Bool
和String
值以及iOS平台感兴趣 - 以及我在几个设备上进行了几百万个读/写周期的测试而没有触发任何类型的错误。因此,即使知道Swift没有提供任何保证,我仍然想知道是否可以合理地依赖平台本身来做到这一点。我更改了标题以反映这一点。