所以我在这里有了我的第一个关闭:
var instructions: (() -> Void) = {
print("First")
}
instructions() /// prints "First"
现在,我有另一个关闭:
let additionalInstructions: (() -> Void) = {
print("Second")
}
additionalInstructions() /// prints "Second"
我想“附加” additionalInstructions
到...的结尾instructions
...这可能吗?我尝试制作一个包含它们的新闭包,如下所示:
let finalInstructions: (() -> Void) = {
instructions()
additionalInstructions()
}
finalInstructions()
此打印
第一
第二
但是,当我更换instructions
使用finalInstructions
,我得到一个EXC_BAD_ACCESS
。
instructions = finalInstructions
instructions() /// error here
我认为这是因为闭包是引用类型,并且在instructions
包含自身时会发生某种循环。有办法避免错误吗?像finalInstructions
容器一样制作一个新的闭合,也似乎很笨拙。
这是我没想到的一些有趣的语义,但是您看到的是无限递归,该递归由于堆栈溢出而崩溃。您可以通过在项目中运行此代码来确认这一点,调试器将在该项目中捕获错误。您将看到数千个相同闭包的堆栈框架被调用。
instructions
闭包中的引用似乎正在捕获其新的自引用值,而不是先前的值。
您使用像这样的新变量的finalInstructions
方法要好得多。不仅因为它避免了这个问题,而且还因为它更具可读性。
这是一个更简单,更简单的问题演示:
var closure = { print("initial definition") }
closure() // prints "initial definition"
closure = {
print("second definition")
closure()
}
closure() // prints "second definition" repeatedly, until the stack overflows
仅供参考,我在Swift论坛上对此进行了询问:https : //forums.swift.org/t/mutable-closures-can-capture-themselves/43228
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句