首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >斯威夫特的懒人

斯威夫特的懒人
EN

Stack Overflow用户
提问于 2018-03-23 01:21:55
回答 2查看 791关注 0票数 0

在阅读了关于Swift的惰性变量之后,我有以下问题:

代码语言:javascript
复制
class MainViewController: UIViewController {

      lazy var heavyClass = HeavyClass()

      func buttonPressed () {
         //Use heavyClass here
         self.heavyClass.doStuff()
      }    
}

因此,您可以使用上面的惰性变量来优化代码,这样heavyClass就不会立即得到分配。因此,在启动时,这将是最优的,因为heavyClass在启动时不会得到分配。

但是,这不是和上面的一样吗?

代码语言:javascript
复制
class MainViewController: UIViewController {

      var heavyClass : HeavyClass?

      func buttonPressed () {
         //Use heavyClass here
         self.heavyClass =  HeavyClass()
         self.heavyClass!.doStuff()
      }    
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-23 01:52:43

在您的示例中,结果并不完全相同,具体如下:

  1. 单次实例化每次调用buttonPressed()时,都会实例化一个新的HeavyClass。在使用lazy关键字时,情况并非如此,后者只会在第一次访问时创建实例。要匹配惰性语义,您必须在每次访问之前检查和设置heavyClass == nil
  2. 无空性。每次要使用heavyClass时,都必须通过可选链(heavyClass?.doStuff())或强制展开(heavyClass!.doStuff())来打开它。还可以将变量设置为nil,这将是第一个示例中的编译器错误。

惰性变量的真正优势是当您有多个使用该变量的位置时。我相信你能在这里发现重复的地方:

代码语言:javascript
复制
func buttonPressed() {
    if self.heavyClass == nil {
        self.heavyClass = HeavyClass()
    }
    self.heavyClass?.doStuff()
}

func aDifferentButtonPressed() {
    if self.heavyClass == nil {
        self.heavyClass = HeavyClass()
    }
    self.heavyClass?.doSomethingElse()
}

这是使用一个惰性变量来整理的:

代码语言:javascript
复制
func buttonPressed() {
    self.heavyClass.doStuff()
}

func aDifferentButtonPressed() {
    self.heavyClass.doSomethingElse()
}
票数 8
EN

Stack Overflow用户

发布于 2018-03-23 01:58:55

解决相同问题的方法有很多种,但我在这里要谈几个。问题是你只想在需要的时候分配内存。在有些情况下,您可能会使用这样或那样的方式,而且它可能会受到编码风格的某种影响。一方面,假设类需要一些设置,所以使用惰性可以提供更好的代码可读性。例如:

代码语言:javascript
复制
lazy var heavyClass: HeavyClass = {
    let heavyClass = HeavyClass()
    heavyClass.attribute1 = X
    heavyClass.attribute2 = X
    heavyClass.attribute3 = X
    heavyClass.attributeAndSoOn = X
    return heavyClass
}()

关键是,这里所有的标准设置都是自包含的,只有在需要时才能获得内存分配的好处。您不必添加函数或延长操作例程(如buttonPressed)。

在另一种情况下,您可以使用选项,但这确实增加了价值为零的可能性。然后,您必须添加逻辑来处理这个问题。

我也见过一款没有包装的模型,但我本人并不使用。看起来是这样的:

代码语言:javascript
复制
class MainViewController: UIViewController {

  var heavyClass : HeavyClass!

  func buttonPressed () {
     //Use heavyClass here
     heavyClass = {
        let heavyClass = HeavyClass()
        // do your other stuff here
        return heavyClass
     }()
    heavyClass.doStuff()
  }    
}

这都是偏好的问题。我要说,懒惰的var也不是线程安全的。因此,如果可以使用该对象拥有多个线程,那么一个线程就有可能访问部分构造的对象。

希望这能有所帮助!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49440974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档