2016-10-11 22 views
3

让我们一个计算的属性开始与代码片段:是什么让一个属性斯威夫特

St Foo { 
    var proA: Int = 0 { // needs initialization 
     willSet { 
      print("about to set proA to \(newValue) from \(proA)") 
     } 
     didSet { 
      print("already set proA to \(proA) from \(oldValue)") 
     } 
    } 

    var ProB: Int { // do not needs initialization 
     return 1 
    } 
} 

let foo = Foo() 
foo.proA = 23 
print(foo.ProB) 

下面是我的一些有关的存储和计算的财产个人理解的:

一:物业只观察者(willSet和didSet)不是一个计算属性,而是一个存储属性(例如上面代码中的proA属性)。

b:计算属性不能有初始化(请参阅上面代码的注释)。

c:setter与属性观察者相同,属性观察者只是setter +观察者对之前和之后的变异。

问题:

我不知道是什么让一个属性计算的财产?只要属性有一个getter并返回它是一个计算属性,它是正确的吗?

2.我的所有理解(a,b & c)是否正确?如果不是的话,你会很高兴指出。

3.为什么不允许初始化计算属性? (请看下图)当我这样做编译器发出警告不能调用非函数类型的值“int”这个错误的含义是什么?

enter image description here

非常感谢。

回答

3

首先,这是约变量,而不是属性任何变量可以是一个计算变量。属性只是使用变量的一种方式。

我认为总的来说,你将一个存储变量与setter观察者并排放在一个计算变量中犯了一个大错误。他们是无关的!

将计算变量看作是当你使用它时看起来和行为像变量的东西 - 你得到(也许)设置它 - 但实际上是一个函数(或一对函数)。这只是调用函数的一种简洁方式。那是全是是。

另一方面,存储变量与观察员,只是一个存储的变量,也有一些观察员。


好了,就到你的问题:

  1. 我不知道是什么让一个属性计算的财产?是正确的,只要属性有一个getter并返回它是一个计算属性?

是的。它是一个计算变量,因为您使用使其成为计算变量的语法(使用花括号)声明它。

  • 都是我的理解(A,B & c)中正确的吗?如果不是会很好的指出
  • 是的。我觉得你的“C”是相当精辟:一个计算的变量不需要二传手观察者因为它有一个二传手(哇!)!

    1. 为什么不允许初始化计算属性? (请参见下图),当我这样做,编译器给出警告不能叫无功能型的价值“INT”这是什么错误的含义是什么?

    计算变量“有”一个值 - 它是计算出来的没有意义!这只是一些功能! - 因此分配一个“初始”值是没有意义的。

    +0

    是的关于“b”选项,你是对的我犯了一个错误,我的意思是“没有”。已经修复 – SLN

    +0

    并看到,总是看到我的书:http://www.apeth.com/swiftBook/ch03.html#_computed_variables – matt

    +0

    感谢您的参考,我现在就读它。我昨天在亚马逊预订了你的书。我正在等待正式发布。 – SLN

    2

    A 存储属性是属性值与类或结构的实例一起存储的属性。该值可能会改变,但该属性也可以是一个常量。因此,一个存储的属性可以是简单的:

    var proA: Int 
    let proB: Int 
    var proC: Int = 0 
    

    计算属性不存储的值。因此您不能将值分配给计算属性。 Computed属性应该有一个返回值的getter。我是一个广义的术语,您可以将计算属性看作是返回函数值的属性。

    计算属性的例子

    var proA: Int { 
        return proB * proC 
    } 
    

    至于你的问题:

    1. 计算属性是为此不存储值的属性,并包含一个get返回“计算'的财产价值。
    2. 一个是正确的,B计算性能不应该有初始化,C,如果你的意思是willSet和didSet。是的,他们是像当属性的值会发生变化,并分别
    3. 改变由于计算的属性不存储的价值,绝不会被用来观察员,编译器禁止它。

    希望这有助于一点。

    +0

    谢谢你的答案,它有助于:) – SLN

    1
    1. 我不知道是什么让一个属性计算的财产?是正确的,只要属性有一个getter并返回它是一个计算属性?

    如果定义get { }财产申报中,它使该属性的计算性能。 并且它不能具有初始值,因为当您访问属性时,它总是会调用get{}函数在属性中声明的函数。

  • 都是我的理解(A,B & c)中正确的吗?如果不将是很好的,你指出

    • 一个是正确的
    • b为错误的。

    您无法为计算属性设置初始值。 因为正如我在问题1中所解释的,当您需要访问该属性时,它总是会返回get{}的结果。

    • C:50%右

    制定者,它也可以被用来作为newValue存储到另一个私有变量,你可以做一些额外的observing逻辑。因此,要观察存储属性的值更改,请使用willSetdidSet 您可以在set{}声明中定义observing关于计算属性(具有gettersetter)的逻辑。但set {}的主要目的是将该值存储到另一个变量或例如UserDefaults

  • 为什么不允许初始化计算属性? (请参见下图),当我这样做,编译器给出警告不能叫无功能型的价值“INT”这是什么错误的含义是什么?

    相同的答案

    您的代码编译器当您上声明属性设置初始值混淆 ,编译器试图把它理解为stored财产。但是您也为此属性定义了get{},这意味着它是计算属性,并且在访问属性时应始终返回22。所以你应该删除其中的一个。

  • +0

    嗨亚历克斯,感谢您的帮助,非常详细的信息:) – SLN

    +0

    谢谢你,这是我的荣幸:) – Alex

    1

    a。是的,一个只有观察者的属性是一个存储属性而不是一个计算属性。属性观察者跟踪一个属性的值,该属性的值之前已经初始化&它现在正在改变,这是一个存储属性。它不适用于计算属性,因为它没有预定义的值

    b。计算属性是一个属性,其值取决于其他变量,我们应该只声明这些属性为计算属性,这些属性需要使用另一个变量的值进行计算,所以它的值无法预先初始化。例如对于例如 - 如果我们有两个变量a & b。我们需要它们的附加值,所以使用一个名为'sum'的变量,那么sum将被声明为一个计算的属性&它的get {}块将返回(a + b),这是总和为& b & sum variable 。那么在这种情况下,我们无法预先初始化属性“总和” ,因为它将使用& b来计算。

    c。 Setter不是一个观察者,它设置另一个变量的值或者执行一些与其他变量相关的操作,而属性观察者追踪其相关变量本身的值的变化。例如,如b点所述,对变量'sum'使用属性观察者是没有意义的。