懒惰的财产的记忆管理

时间:2017-01-05 06:58:20

标签: swift properties lazy-evaluation

当我快速学习时,我发现懒惰的概念有点令人困惑。

懒惰属性在类实例需要或访问时初始化

   class Employee
        {
            var name : String
            lazy var salary = Salary(Basic : 25000 ,HRA : 3000 , DA : 4000)    
            lazy var minExperience = 0 


     init(nameValue :String)
        {
            name = nameValue 

       } }

    var emp1 = Employee("John") // Here the minExperience and 
//salary will be nil as they are not assigned any space = 

//emp1.salary.storage = nil , emp1.minExperience.storage = nil 


// now access the minExperience

emp1.minExperience // using 1st time and this will return 0 !  emp1.salary.HRA // using 1st time and this will return 3000 !

所以我的问题是:

  1. 由于minExperiencesalary没有分配任何存储空间,所以在我们访问它之前,它会将值存储在哪里 - 03000 ???

  2. Lazy属性的一个方面是

      

    当属性的初始值依赖于外部因素时,延迟属性非常有用,这些外部因素的值在   实例的初始化已完成。

  3. 那么为什么Xcode迫使我们在声明时分配值?

    1. 由于我们已经为Lazy属性赋值,显然我们不需要在init方法中初始化它。

2 个答案:

答案 0 :(得分:1)

惰性变量仍然会分配它所需的内存。它只是推迟了初始化代码的执行。

这是常规变量的唯一区别,在这两种情况下,编译器都需要一个值来分配(最初或在第一次引用时)。

在你的例子中,

薪水似乎是懒惰变量的一个很好的候选者,因为它需要一个函数来获取初始值,并且可能是在创建Employee对象时该函数未准备好运行,或者系统执行成本太高(并且可以等待工资变量的实际使用)

另一方面,minExperience没有计算其初始值,也没有因为懒惰而受益。

如果我们没有惰性变量,我们可以使用内部变量和计算属性获得相同的结果:

 internal var _salary : Salary! = nil
 var salary:Salary
 {  
    get {
           if _salary == nil
           { _salary = Salary(Basic : 25000 ,HRA : 3000 , DA : 4000) }
           return _salary 
        }

    set { _salary = newValue }
 }

这(近似地)说明了编译器使用惰性变量执行的操作。

结果相同,但需要更多代码。

答案 1 :(得分:0)

  1. 该类不存储延迟属性值。相反,它只在您第一次引用它时初始化延迟属性:
  2.   

    惰性存储属性是一个初始值不是的属性   计算直到第一次使用。

    1. 您需要在声明时分配一个值,因为编译器需要知道如何在时间到来时初始化惰性属性。但是,如果你想分配依赖于实例(self)或其他对象的值,你也可以定义一个闭包,在那里你可以访问self,因此可以访问因为在实例之后调用闭包而不知道的外部因素。初始化。
    2. 例如,在您的示例中,您可以这样做:

      class Employee {
         var name : String
         lazy var minExperience = 0
         lazy var salary:Salary =  { [unowned self] in
             if self.name.characters.count > 0 {
                 return Salary(Basic : 25000 ,HRA : 3000 , DA : 4000)
             }
             else {
                 return Salary(Basic : 0 ,HRA : 0 , DA : 0)
             }
         }()
      
         init(nameValue :String) {
             name = nameValue
         } 
      }
      

      薪水是一个惰性属性的事实意味着你可以在闭包中引用self,因为只有在初始化完成并且知道self存在之后才会访问lazy属性。

      添加了[unowned self] in以防止泄漏。

      1. 你是对的,我们不需要在init方法中初始化延迟属性,因为这是懒惰属性的重点,我们在初始化时不知道它们的值或者不想初始化在初始化课程中。
相关问题