• Swift


    //: Playground - noun: a place where people can play
    
    import UIKit
    
    // 值类型:指的是当一个变量赋值给另外一个变量的时候, 是copy一个副本
    // 两个变量之间互不影响, 也就是说, 另外一个变量的值改变, 不会影响到另外一个变量
    // 也就是传的只是一个值, 不是一个引用(地址)
    var a = 0
    var b = a
    b = 2
    a
    
    // 闭包和函数都是引用类型
    // 引用类型:指的是当引用类型变量赋值给另外一个变量的时候, 其实两个变量指的都是同一个内容
    // 当其中一个变量修改了这个内容, 另外一个变量也会跟着改变
    func calcTotalMiles(todayMiles: Int) -> () -> Int
    {
        var totalMiles = 0
        return {
            totalMiles += todayMiles;       // 这个闭包用到了Capturing Values
            return totalMiles
        }
    }
    
    var dailyTwoMiles = calcTotalMiles(2)
    dailyTwoMiles()
    dailyTwoMiles()
    
    var myPlan = dailyTwoMiles
    myPlan()
    myPlan()
    
    /*
    同学A的理解:
    var totalMiles = 0 这句是处在 calcTotalMiles 函数中。
    而你说的每次调用,调用的并不是 calcTotalMiles 这个函数,
    而是 calcTotalMiles 这个函数的返回值,也就是另一个函数。
    返回的函数被命名为 dailyTwoMiles 或者 dailyThreeMiles,
    返回函数的内容是闭包内容:{totalMiles += todayMiles; return totalMiles; },
    其中并没有对 totalMiles 重置的语句,所以totalMiles不会被重置。
    那么问题来了,totalMiles 什么时候被重置。
    很简单,var totalMiles = 0 处在 calcTotalMiles 函数中,
    当然是 calcTotalMiles 被调用时会被重置,
    也就是 
    var dailyTwoMiles = calcTotalMiles(2) 和 
    var dailyThreeMiles = calcTotalMiles(3) 
    这两句在运行时会重置 titalMiles.
    
    同学B的理解:
    这里的关键是:calcTotalMiles返回了一个函数,这个函数以闭包的形式返回,我们没有给他起名,
    这里姑且叫他resultFunction。要注意,这个resultFunction和calcTotalMiles不是一个东西,
    resultFunction是calcTotalMiles的一个结果!
    仔细看这个resultFunction函数体内,涉及的两个变量:totalMiles和todayMiles,
    都没有在resultFunction里定义。那resultFunction是怎么拿到这个值的呢?
    这个过程是swift使用一种称为Capturing Values的方式感知到的。与此同时,一点儿没有错,这将产生内存方面的问题。
    在这里,你可以理解成,我们给calcTotalMiles传入一个参数,返回了一个函数resultFunction,
    之后执行calcTotalMiles所使用的栈空间并没有被释放,因为产生的resultFunction还在使用(或者是拥有)调用者calcTotalMiles的内容。
    
    我个人的理解是:
    由于calcTotalMiles的返回值是resultFunction, 而resultFunction又引用着calcTotalMiles中的变量, 
    所以calcTotalMiles执行完之后并没有被销毁, 还保留在内存中...
    所以当resultFunction再次调用的时候所拿到的totalMiles还没有被初始化..就会继续累加...
    */
    
    // ps: 在实际中, 很少用到函数和闭包是引用类型这种情况, 这里仅仅作为了解...
    

      

  • 相关阅读:
    服务器开启超线程
    redhat用kickstart.cfg自动安装后,挂载ISO镜像并从中拷贝文件
    关于网卡特性TSO、UFO、GSO、LRO、GRO
    Linux 网卡特性配置ethtool详解
    SecureCRT设置标签显示标题
    关闭SecureCRT的声音
    SecureCRT设置Vim显示颜色
    centos关闭swap分区
    制作CentOS7.6 自动安装ISO镜像光盘
    带阵列卡的机器打开磁盘cache
  • 原文地址:https://www.cnblogs.com/Rinpe/p/5173368.html
Copyright © 2020-2023  润新知