6

コード スニペットから始めましょう。

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)

保存および計算されたプロパティに関する私の個人的な理解の一部を次に示します。

a: オブザーバーのみを持つプロパティ (willSet および didSet) は、計算されたプロパティではなく、格納されたプロパティです (例: 上記のコードのproAプロパティ)。

b: 計算されたプロパティには初期化があってはなりません (上記のコードのコメントを参照してください)。

c: セッターはプロパティ オブザーバーと同じようなものです。プロパティ オブザーバーは、変更前と変更後のセッター + オブザーバーです。

質問:

1.プロパティを計算プロパティにする理由は何ですか? プロパティにゲッターがあり、計算されたプロパティであるというのは正しいですか?

2.私の理解 (a、b、c) はすべて正しいですか? そうでない場合は、ご指摘いただければ幸いです。

3.計算されたプロパティを初期化できないのはなぜですか? (下の図を参照してください) そして、そうすると、コンパイラは警告を出します Cannot call value of none-function type "int"このエラーの意味は何ですか?

ここに画像の説明を入力

どうもありがとう。

4

4 に答える 4

4

まず、これはプロパティではなく、変数に関するものです。任意の変数を計算変数にすることができます。プロパティは、変数を使用する 1 つの方法にすぎません。

全体として、格納された変数とセッターオブザーバーを計算された変数と並べて配置することは大きな間違いだと思います。それらは無関係です!

計算された変数は、使用時に変数のように見え、機能するものと考えてください — 取得して (おそらく) 設定します — しかし、実際には関数 (または関数のペア) です。関数を呼び出すコンパクトな方法です。それだけです

一方、オブザーバーを含むストアド変数は、いくつかのオブザーバーも含む単なるストアド変数です。


さて、あなたの質問に進みます:

  1. プロパティが計算されたプロパティになる理由は何ですか? プロパティにゲッターがあり、計算されたプロパティを返す限り、それは正しいですか?

はい。計算変数にする構文 (中かっこを使用) を使用して宣言したため、これは計算変数です。

  1. 私の理解 (a、b、c) はすべて正しいですか? そうでない場合は、指摘していただければ幸いです

はい。あなたの「c」は非常に洞察に満ちていると思います.計算された変数には、セッターがあるため、セッターオブザーバーは必要ありません!

  1. 計算されたプロパティを初期化できないのはなぜですか? (下の図を参照してください) そして、そうすると、コンパイラは警告を出します Cannot call value of none-function type "int" このエラーの意味は何ですか?

計算された変数が値を「持つ」ことに意味はありません — それは計算されたものです! それはほんの一部の機能です!— したがって、「初期」値を割り当てても意味がありません。

于 2016-10-11T20:40:25.637 に答える
3

格納されたプロパティは、プロパティ値がクラスまたは構造体のインスタンスと共に格納されるプロパティです。値は変更できますが、プロパティは定数にすることもできます。したがって、保存されたプロパティは次のように単純になります。

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

計算されたプロパティは値を格納しません。したがって、計算されたプロパティに値を割り当てることはできません。計算済みプロパティには、値を返すゲッターが必要です。広い意味で、計算されたプロパティは、関数の値を返すプロパティと考えることができます。

計算されたプロパティの例

var proA: Int {
    return proB * proC
}

あなたの質問に関して:

  1. そのため、計算済みプロパティは、値を格納しないプロパティであり、プロパティの「計算済み」値を返すための get が含まれています。
  2. a は正しいです。b 計算されたプロパティは初期化されるべきではありません。c は willSet と didSet を意味する場合です。はい、それらは、プロパティの値がいつ変更されるか、およびそれぞれ変更されたかのオブザーバーのようなものです
  3. 計算されたプロパティの値は保存されず、決して使用されないため、コンパイラはそれを禁止します。

これが少し役立つことを願っています。

于 2016-10-11T20:44:06.537 に答える
1

を。はい、オブザーバーのみのプロパティは、計算されたプロパティではなく、保存されたプロパティです。定義済みの値がないため、計算されたプロパティには適用できません

b. 計算されたプロパティは、値が他の変数に依存するプロパティです。別の変数の値を使用して計算する必要があるプロパティのみを計算されたプロパティとして宣言する必要があるため、値を事前に初期化することはできません。例 - 2 つの変数 a と b がある場合。加算値が必要なので、「sum」という名前の変数が使用されます。その後、sum は計算されたプロパティとして宣言され、その get{} ブロックは (a+b) を返します。これは、a & b & sum 変数の値の合計です。 .次に、この場合、プロパティ 'sum' を事前に初期化することはできません。これは、a & b を使用して計算されるためです。

c. セッターはオブザーバーではなく、別の変数の値を設定したり、他の変数に関連するアクションを実行したりしますが、プロパティオブザーバーは関連する変数自体の値の変化を追跡します。たとえば、ポイント b で説明されているように、変数 'sum' にプロパティ オブザーバーを使用しても意味がありません。

于 2017-07-10T17:19:15.407 に答える
1
  1. プロパティが計算されたプロパティになる理由は何ですか? プロパティにゲッターがあり、計算されたプロパティを返す限り、それは正しいですか?

get { }プロパティ宣言内で定義すると、そのプロパティが計算されたプロパティになります。また、プロパティにアクセスするときは常にプロパティでget{}宣言された関数を呼び出すため、初期値を持つことはできません。

  1. 私の理解 (a、b、c) はすべて正しいですか? そうでない場合は、指摘していただければ幸いです

    • 正解です
    • bは間違っています。

    計算されたプロパティの初期値を設定できません。質問1で説明したget{}ように、プロパティへのアクセスが必要な場合は常に結果が返されるためです。

    • c : 50% 右

    newValuesetter 、別のプライベート変数に格納するためにも使用でき、追加のobservingロジックを実行できます。したがって、保存されたプロパティの値の変化を観察するには、宣言時にwillSetand を使用して、計算されたプロパティ ( andを持つ) にロジックをdidSet 定義できます。ただし、主な目的は、値を別の変数またはたとえば に格納することです。observinggettersetterset{}set {}UserDefaults

  2. 計算されたプロパティを初期化できないのはなぜですか? (下の図を参照してください) そして、そうすると、コンパイラは警告を出します Cannot call value of none-function type "int" このエラーの意味は何ですか?

    同じ答え

    あなたのコードはコンパイラを混乱させます 宣言時にプロパティに初期値を設定すると、コンパイラはそれをstoredプロパティとして理解しようとします。ただし、このプロパティも定義get{}しました。これは、計算されたプロパティであり22、プロパティにアクセスすると常に返される必要があることを意味します。したがって、2 つのうちの 1 つを削除する必要があります。

于 2016-10-11T20:46:24.457 に答える