[英]How can use @escaping for a func which used in didSet without using a reference type in Swift?
这个向下的代码工作得很好! 一旦我用'@escaping'更新testFunc,它就会开始出错
转义闭包捕获变异的“自我”参数
struct TestType {
var string: String {
didSet(oldValue) {
if (oldValue != string) {
testFunc(string: string, result: { resultValue in
value = resultValue
})
}
}
}
private(set) var value: String
}
func testFunc(string: String, result: (String) -> Void) {
result(string + " updated!")
}
我的目标是能够使用:
func testFunc(string: String, result: @escaping (String) -> Void) {
result(string + " updated!")
}
如何在不使用引用类型的情况下解决问题?
在struct
中的@escaping
闭包中捕获变异self
的问题在于,理论上 Swift 可能会尝试如何做到这一点实际上只有两种选择。
第一个是捕获对struct
的引用,但在许多情况下它存在于堆栈中。 由于可以稍后调用@escaping
闭包,这意味着写入堆栈上self
所在的位置,但可能不再存在。 如果在堆栈缩小时发生这种情况,那么您正在写入一个任何其他代码实际上都无法访问的地址。 如果它发生在堆栈重新增长(或更大)时,那么您可能会踩到不相关的数据,可能是某个函数的返回地址。 如果幸运的话,结果将是程序崩溃。 如果你不走运,它会默默地做错事。
另一种可能的实现是 Swift 可以捕获一个副本,当然,可以安全地写入该副本,但任何其他代码都无法访问。 这很没有意义。
Swift 还有第三种选择,它可以将结构装箱(实际上就是将它放在堆上)。 问题是没有其他人会知道堆位置。 同样,这毫无意义……而且比在堆栈上分配东西要慢得多。
如果你真的需要捕获一个变异的self
,那么你需要TestType
是一个class
,但这意味着你的其余代码必须在编写时考虑到引用语义。
很有可能,您需要考虑以不同的方式尝试解决的任何问题。 如果不知道那是什么,就不可能提出具体的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.