闭包的值是如何被保存下来的?

来源:8-4 Swift-值类型和引用类型

快到小利碗里来

2014-12-04 12:02

这块的值为什么可以保存下来,函数调用,函数变量是无法保存的,每次调用都会重新在栈上开辟空间,然后赋值使用,而闭包跟函数具有相同的功能,不同的是它的变量是从外界传入的,难道它实在静态代码段被生成的吗?

写回答 关注

3回答

  • dqmore
    2014-12-17 22:00:12

    javascript高级开发一本书也有说到这个问题,,语言之间好多都相同

  • 快到小利碗里来
    2014-12-04 22:46:23

    你的意思是说,引用计数的机制来标记内存使用情况,以此来决定是否进行内存回收?

    那你是说这个函数调用的过程是在堆上建立的吗?

    忽然想了一下,可以在调用calcTotalMiles的时候打印一下当前变量Total的值,测试一下。

    因为之前没接触过ios产品开发,所以对它的内存结构但还是不是很明白(是否在栈空间分配内存)。写了下面一段代码,希望给个解释,另外,有没有像GDB之类的比较给力的Debug工具推荐一下,谢谢


    func calcTotalMile(todayMiles:Int) -> () -> Int {

        var totalMiles: Int = 0

        println("in calcTotalMile: tatalMiles: \( totalMiles )")

        return {

            println("in closure: totalMiles: \(totalMiles)")

            totalMiles += todayMiles

            return totalMiles

        }

    }


    var dailyTowMiles = calcTotalMile(2)

    dailyTowMiles()

    dailyTowMiles()


    var dailyThreeMails = calcTotalMile(3)

    dailyThreeMails()

    dailyThreeMails()


    dailyTowMiles()


  • l1uyub0b0b0
    2014-12-04 20:27:26

    这是一个很深入的话题。我正在策划后续做swift的高级课程时或许会涉及。


    这里的关键是:calcTotalMiles返回了一个函数,这个函数以闭包的形式返回,我们没有给他起名,这里姑且叫他resultFunction。要注意,这个resultFunction和calcTotalMiles不是一个东西,resultFunction是calcTotalMiles的一个结果!


    仔细看这个resultFunction函数体内,涉及的两个变量:totalMiles和todayMiles,都没有在resultFunction里定义。那resultFunction是怎么拿到这个值的呢?这个过程是swift使用一种称为Capturing Values的方式感知到的。与此同时,一点儿没有错,这将产生内存方面的问题。在这里,你可以理解成,我们给calcTotalMiles传入一个参数,返回了一个函数resultFunction,之后执行calcTotalMiles所使用的栈空间并没有被释放,因为产生的resultFunction还在使用(或者是拥有)调用者calcTotalMiles的内容。


    那么现在问题来了:什么时候calcTotalMiles的空间会被真正释放?在这个例子里,swift的ARC(Auto Reference Counting)机制会帮我们自动处理。我们不需要处理内存的问题。但是,这样的一种机制确实会产生循环引用的问题。这就是我说的,我策划在后续介绍的swift高级课程里要涉及的内存管理相关内容:。


玩儿转Swift

这套教程比任何的Swift中文教程深入,并且演示示例更丰富

57181 学习 · 511 问题

查看课程

相似问题