Swift getter 覆盖非计算变量

Posted

技术标签:

【中文标题】Swift getter 覆盖非计算变量【英文标题】:Swift getter override non-computed variable 【发布时间】:2014-11-04 16:31:23 【问题描述】:

在 Objective-C 中,能够做到这一点真的很容易也很好

 - (UIButton *)backButton
      if(!_backButton)
           _backButton = [UIButton new];
      
 

然而,在 Swift 中,当您覆盖属性 getter 时,它被称为计算变量,并且每次访问 self.backButton 时,都会重新计算该变量。下面的例子很好地说明了这一点:

private var backButton: UIBarButtonItem 
    let button = UIButton(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width*0.06, height: self.view.frame.size.width*0.06))
    button.setImage(UIImage(named: "back_arrow"), forState: UIControlState.Normal)
    button.rac_signalForControlEvents(UIControlEvents.TouchUpInside).subscribeNext 
        (next: AnyObject!) -> () in
        self.navigationController?.popViewControllerAnimated(true)
        return ()
    
    println("Recalculating the button")
    let item = UIBarButtonItem(customView: button)
    return item

每次访问 self.backButton 时都会调用 println 语句。另外,每次打印出来的内存地址也会发生变化。我知道这是计算变量的本质,因为它们不存储在内存中。

这是在 Swift 中复制 Obj-C 中所见行为的类似方法吗?我想要的只是一种实例化某个 UI 变量的方法,而无需将该代码放入初始化方法中。

【问题讨论】:

【参考方案1】:

您所指的是“延迟实例化”。 您可以使用 lazy 关键字快速复制它:

private lazy var backButton: UIBarButtonItem = 
      let button = .....
      //....
      return button
  ()

【讨论】:

这实际上是行不通的,因为你需要UIBarButtonItem = ,然后是底部的()。 @David 做对了【参考方案2】:

最好的方法可能是将它创建为一个惰性变量,这样初始化器将在第一次被访问时被调用一次。

lazy var backButton:UIBarButtonItem = 
    let button = ...
    return button
 ()

通过使用初始化块,您可以提供实例变量的复杂初始化。

【讨论】:

以上是关于Swift getter 覆盖非计算变量的主要内容,如果未能解决你的问题,请参考以下文章

Swift 中的惰性属性相当于 Objective C 中的惰性 Init getter

Swift 属性的多个 Getter?

《从零开始学Swift》学习笔记(Day 32)——计算属性

swift:谈谈swift几种常见属性的区别

是否可以在扩展中使用非只读计算属性?

计算属性的getter和setter