【问题标题】:How properties( stored and computed) are accessed during instantiation?在实例化期间如何访问属性(存储和计算)?
【发布时间】:2016-06-07 16:12:36
【问题描述】:

我正在学习 CS193 课程。从video的这一刻开始。

选项 1:

class FaceView: UIView
{
    var scale: CGFloat = 0.90
    var mouthCurvature: Double = 1.0 

    private var skullRadius: CGFloat {
        return min(bounds.size.width, bounds.size.height) / 2 * scale
    }
 }

为什么我不能写

选项 2:

class FaceView: UIView
{
    var scale: CGFloat = 0.90
    var mouthCurvature: Double = 1.0 

    private var skullRadius = min(bounds.size.width, bounds.size.height) / 2 * scale

 }

教授解释说,您在初始化期间无法访问自己的属性,因此如果您执行选项 2,您将收到错误消息:instance member 'bounds' cannot be used on type 'FaceView'

好的,但我们不是还在访问选项 1 中的实例成员“bounds”吗?有什么不同?或者是访问是可以的,但是你不能让一个属性依赖于另一个初始化期间?

【问题讨论】:

  • 不同之处在于您何时访问它。在选项 2 中,faceview 尚未实例化,因此它没有边界
  • 我想我无法将我的问题传达给你,我已经知道了......它是如何在选项 1 中被视为实例化的?我们在那里做什么不同?只需returning 并解决问题对我来说并不神秘......
  • scalemouthCurvatureFaceView 的实例被实例化时被初始化。您的计算属性 skullRadius 是在实例化对象在实例化之后调用该属性时计算的。在另一种情况下,skullRadius 是常规属性,它是在实例化时设置的,因此其他成员尚不可用。

标签: swift initialization cs193p


【解决方案1】:

这是存储属性和计算属性之间的区别之一。

scalemouthCurvature 的存储属性在FaceView 的实例被实例化时被初始化。

在您的第一个示例中,skullRadius 是一个计算属性,当您的 FaceView 实例在实例化后调用该属性时计算该属性。

在第二个示例中,skullRadius 是一个在实例化时初始化的存储属性。其他属性此时尚不可用,因为它们可能已初始化,也可能未初始化。

在初始化期间如何引用另一个属性:

class test {
  let foo = 1 // stored property
  let bar = 2 // stored property
  let buzz: Int // stored property not initialized when other stored properties are initialized
  init() {
    buzz = foo + bar // initialized after other stored properties
  }
}

展示如何修改惰性属性的示例:

class Test {
  lazy var foo: Int = { return 5 }()
}

let test = Test()
print(test.foo) -> "5"
test.foo = 10
print(test.foo) -> "10"

【讨论】:

  • 您可以通过lazy var someStoredProperty: T = { ...return x }() 解决它。
  • 是的,差不多就是这样。如果您在 init 方法中设置它,您还可以使用存储属性并引用其他存储属性。 init 方法在存储的属性被初始化之后发生。我已经更新了我的答案以显示这一点。
  • @jtbandes 正确,惰性属性可以与闭包或函数调用一起使用,以便在以后设置它。但是,必须使用var 而不是let 声明该属性。在某些情况下,这可能是个问题。
  • @Honey 我的 Objective-C 有点生疏,但我认为这个问题根本不适用于 Swift。
  • @Honey 计算(和惰性)属性仅在请求时发生 因此仅在实例化之后发生。
猜你喜欢
  • 2018-12-08
  • 2018-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-14
  • 1970-01-01
  • 2017-06-11
  • 2010-11-21
相关资源
最近更新 更多