在后台线程中自变异 Swift 结构
Self-mutate Swift struct in background thread
假设我们有一个能够自我突变的结构,它必须作为后台操作的一部分发生:
struct Thing {
var something = 0
mutating func operation(block: () -> Void) {
// Start some background operation
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
// Mutate self upon background task completion
self.something += 1
block()
}
}
}
现在,当我在上下文中使用这样的结构时:
var myThing = Thing()
myThing.operation {
println(myThing.something)
}
println
给了我 0
,就好像 myThing
从未发生过变异一样。从 dispatch_async
中打印 self.something
显然会产生 1
.
我该如何解决这个问题,最好是不必在 operation
竞争块中传递更新的结构 self
并覆盖主上下文中的原始变量?
// Ew
var myThing = Thing()
myThing.operation {
(mutatedThing) in
myThing = mutatedThing
println(myThing.something)
}
我已经多次看到这个确切的问题,但没有更多细节,我不能说它是否出于与您遇到它相同的原因而发生。
这让我发疯,直到我意识到分派的操作发生在不合逻辑的时间,即通常 在 当前时间之前。在调度块的参考框架中,它正确更新了变量,这就是它从块内部正确打印出来的原因。但是在"real world"中,由于某种原因,dispatch被认为从未发生过,值的变化被丢弃了。或者可能是因为突变隐式地创建了一个新结构并且因为它是 "time travelling" 对它的引用从未更新过。不能说。
就我而言,一旦我正确安排了发货时间,问题就消失了。希望对您有所帮助!
我正在添加第二个答案,因为我的第一个答案解决了不同的问题。
我自己也遇到了这个困难,情况和你几乎一模一样。
在努力找出发生了什么并修复它之后,我意识到问题基本上是在应该使用引用类型的地方使用了值类型。
闭包似乎创建了结构的副本并对其进行操作,而原始结构保持不变——这更符合值类型的行为。
另一方面,期望的行为是闭包中执行的操作由闭包外部的环境保留——换句话说,需要引用两个不同的上下文(闭包内部和外部)到相同的对象——这更符合引用类型的行为。
长话短说,我将结构更改为 class。问题消失了,不需要其他代码。
假设我们有一个能够自我突变的结构,它必须作为后台操作的一部分发生:
struct Thing {
var something = 0
mutating func operation(block: () -> Void) {
// Start some background operation
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
// Mutate self upon background task completion
self.something += 1
block()
}
}
}
现在,当我在上下文中使用这样的结构时:
var myThing = Thing()
myThing.operation {
println(myThing.something)
}
println
给了我 0
,就好像 myThing
从未发生过变异一样。从 dispatch_async
中打印 self.something
显然会产生 1
.
我该如何解决这个问题,最好是不必在 operation
竞争块中传递更新的结构 self
并覆盖主上下文中的原始变量?
// Ew
var myThing = Thing()
myThing.operation {
(mutatedThing) in
myThing = mutatedThing
println(myThing.something)
}
我已经多次看到这个确切的问题,但没有更多细节,我不能说它是否出于与您遇到它相同的原因而发生。
这让我发疯,直到我意识到分派的操作发生在不合逻辑的时间,即通常 在 当前时间之前。在调度块的参考框架中,它正确更新了变量,这就是它从块内部正确打印出来的原因。但是在"real world"中,由于某种原因,dispatch被认为从未发生过,值的变化被丢弃了。或者可能是因为突变隐式地创建了一个新结构并且因为它是 "time travelling" 对它的引用从未更新过。不能说。
就我而言,一旦我正确安排了发货时间,问题就消失了。希望对您有所帮助!
我正在添加第二个答案,因为我的第一个答案解决了不同的问题。
我自己也遇到了这个困难,情况和你几乎一模一样。
在努力找出发生了什么并修复它之后,我意识到问题基本上是在应该使用引用类型的地方使用了值类型。
闭包似乎创建了结构的副本并对其进行操作,而原始结构保持不变——这更符合值类型的行为。
另一方面,期望的行为是闭包中执行的操作由闭包外部的环境保留——换句话说,需要引用两个不同的上下文(闭包内部和外部)到相同的对象——这更符合引用类型的行为。
长话短说,我将结构更改为 class。问题消失了,不需要其他代码。