Ios 努力理解为什么;通过引用捕获可确保runningTotal和amount不会在调用makeIncrementer结束时消失';?
我是Swift的新手,正在努力学习捕捉价值的概念。我从“Swift编程语言2.1”中看到了这一点: incrementer()函数没有任何参数,但是 指其函数体中的运行总计和金额。它 通过从 围绕函数并在其自身的函数体中使用它们。 通过引用捕获可确保runningTotal和amount不会 在调用makeIncrementer结束时消失,并确保 runningTotal在下次使用递增函数时可用 打电话来。” 如果我要问的问题对你们中的一些人来说听起来简单或愚蠢,请原谅我,但这一直让我很困扰 问题1。为什么“通过引用捕获可以确保在调用makeIncrementer结束时runningTotal和amount不会消失” 问题2。为什么“通过引用捕获可以确保下次调用递增函数时runningTotal可用”Ios 努力理解为什么;通过引用捕获可确保runningTotal和amount不会在调用makeIncrementer结束时消失';?,ios,swift,reference,closures,capture,Ios,Swift,Reference,Closures,Capture,我是Swift的新手,正在努力学习捕捉价值的概念。我从“Swift编程语言2.1”中看到了这一点: incrementer()函数没有任何参数,但是 指其函数体中的运行总计和金额。它 通过从 围绕函数并在其自身的函数体中使用它们。 通过引用捕获可确保runningTotal和amount不会 在调用makeIncrementer结束时消失,并确保 runningTotal在下次使用递增函数时可用 打电话来。” 如果我要问的问题对你们中的一些人来说听起来简单或愚蠢,请原谅我,但这一直让我很困扰 问
我发现很难在脑海中描绘和理解这些陈述。有人能帮我吗?提前感谢您的帮助 Swift通过(自动引用计数)自动进行内存管理。在高级别上,当针对某个对象创建(强)引用时,计数器会增加。如果引用计数器大于0,则不会从内存中释放对象 因此,通过创建引用(在从父函数捕获值时发生),您可以确保内存没有释放。如所述: Q1。为什么“通过引用捕获可以确保在调用makeIncrementer结束时runningTotal和amount不会消失” A1。每次调用
incrementByTen
,对makeIncrementer
的调用都会结束。但是runningTotal
的值仍然没有消失,您可以在输出中看到这一点
Q2。为什么“通过引用捕获可以确保下次调用递增函数时runningTotal可用”
A2。每次调用
incrementByTen
,都会调用incrementer
。每次通过incrementByTen
调用incrementer
时,您都有runningTotal
的修改值。这也可以从输出中看到。runningTotal
是一个Int
值类型,不受参考计数的影响。ARC只对引用类型(即类的实例)执行。如果我错了,请纠正我,Martin,但函数也是引用类型。(根据文档中标题为“闭包是引用类型”的部分,结合函数是闭包的特例这一事实)。我还没有在这方面找到好的资源,但是嵌套函数似乎通过对父函数本身的引用来“关闭”父函数的值。这是正确的,也许我误解了您的答案(在这种情况下我很抱歉!)——您没有明确说明引用计数是多少。问题(据我所知)是什么让runningTotal
变量保持活动状态。是的-我不想把它放在我的答案中,因为我不知道引用的是什么-闭包指南说“当不再需要变量时,Swift还处理所有涉及到处理变量的内存管理。”这意味着弧。仅仅因为我们作为swift程序员不能传递一个Int
作为引用,这并不意味着编译器不能,而且据我所知,这可能会在幕后发生。
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrement(forIncrement: 10)
incrementByTen()
Calling the function multiple times shows this behavior in action:
incrementByTen()
// returns a value of 10
incrementByTen()
// returns a value of 20
incrementByTen()
// returns a value of 30