【问题标题】:swift: Is correct to use stored properties as computed propertiesswift:使用存储属性作为计算属性是正确的
【发布时间】:2014-08-02 09:28:59
【问题描述】:

我正在尝试实现这个目标-c 代码

@property (strong) UIView *customView;

-(UIView*)customView
{
   if (!customView){
       self.customView = [[UIView alloc]init];
       self.customView.backgroundColor = [UIColor blueColor];
  }
   return customView;
}

我为什么要用这个? customView 从很多地方调用,所以我们必须在所有地方检查这个条件。为了避免这种重复,我写了这个。

所以我尝试创建存储属性并使用 getter 方法检查是否已经创建。

var mainView : UIView? {

  get{
   if let customView = self.mainView{
        return self.mainView
   }
   var customView : UIView = UIView() 
   self.mainView = customView
   self.mainView.backgroundColor = UIColor(blueColor)
   return customView 
 }
 set{
  self.mainView = newValue
  }
}

这是正确的吗?或任何其他方法来做到这一点?

注意:上面的代码没有警告或错误。但是与存储和计算属性混淆。请让我清楚。

【问题讨论】:

标签: ios swift


【解决方案1】:

这被称为惰性属性。只需像任何其他存储属性一样声明它,但使用 @lazy 修饰符。该对象将在有人第一次尝试获取它时创建。你不需要为自己写那些东西。

请参阅the Swift Book 中的“惰性存储属性”。你只需写:

@lazy var customView = UIView()

【讨论】:

  • 可以做加法运算吗?喜欢设置背景颜色...?
【解决方案2】:

不知道为什么,但是惰性变量与计算属性相结合会导致错误:

'lazy' attribute may not be used on a computed property

但这似乎有效:

class MyClass {
  @lazy var customView: NSView = {
    let view = NSView()
    // customize view
    return view
  }()
}

【讨论】:

  • 我猜计算属性本质上是惰性的。它们在被访问时而不是之前被计算。
  • 这是一个很好的解决方案,可以在惰性存储属性中进行一些复杂的初始化。它本质上是调用闭包 (() -> NSView)() 来进行初始化,而不是直接调用初始化程序,例如。 NSView().
  • 效果很好:)。现在接受这个答案。如果我得到更好的答案,我会更新。:)
  • @MikePollard 虽然计算属性在被访问时被计算,但它没有被记忆,即它的返回值没有被保存。因此,计算属性每次被访问时都会被计算。我不会说那是懒惰的。 :-) 另一方面,惰性存储属性仅在第一次访问时才计算,因为它已被记忆,因此,每次后续访问都只返回保存的值。
【解决方案3】:

swift 2.1 中的等价物应该如下:

var _customView:UIView? = nil
var customView:UIView {
    if _customView == nil
    {
        _customView = UIView.init()
        _customView?.backgroundColor = UIColor.blueColor()
    }
    return _customView!
}

另外,为了避免多次调用customView的getter,我会将你原来的objective-C代码写成如下:

@property (strong) UIView *customView;

// @synthesize customView; // make sure you didn't add this line

- (UIView*)customView
{
   if (!_customView){
       _customView = [[UIView alloc] init];
       _customView.backgroundColor = [UIColor blueColor];
   }
   return customView;
}

【讨论】:

    猜你喜欢
    • 2017-06-11
    • 2022-08-16
    • 2017-02-20
    • 2015-04-18
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多