Swift - 37 - 值类型和引用类型的简单理解
//: 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: 在实际中, 很少用到函数和闭包是引用类型这种情况, 这里仅仅作为了解...