2016-07-20 15 views
5

私は怠惰な動作を迅速に理解しようとしています。次のコードはエラーなしでコンパイルされます。遅延変数を使用するとコンパイルエラーが発生する

import UIKit 
class Test : UIViewController{ 
    let i = 1 
    lazy var j:Int = self.i 
} 

私はJのタイプを削除すると、それは以下のコードのように推測させる、

import UIKit 
class Test : UIViewController{ 
    let i = 1 
    lazy var j = self.i 
} 

場合のに対し、私はタイプのコンパイルエラー」の値を取得する 『NSObjectの - >() - >テスト』していますno member 'i' "

誰かがコンパイラで何が起こっているのか説明できますか?ありがとう

答えて

4

あなたはここで3つの側面を考慮する必要があります。

  • 遅延記憶されたプロパティは、その初期値 は、それが使用される最初の時間まで計算されない特性です。それは初めて と呼ばれ、その値が計算されます。
  • 実際の値は評価によって作成されるため、遅延変数のデータ型を先に と宣言する必要があります。
  • クラスに宣言するプロパティは、インスタンス変数( )です。値にアクセスする必要がある場合は、インスタンス(オブジェクト)がクラス である必要があります。

私たちは、あなた以外の作業コード

lazy var j = self.i 

2つの問題から行を以下の点を考慮してみましょうあなたの非作業コードに存在しています。まず、あなたのlazy varのデータ型を指定していません。宣言が不完全であるため、コンパイラは 'j'を処理する遅延ライブラリとして扱いません。これは、通常のインスタンス変数として扱われます。クラス内の変数を宣言するたびに、その変数に値を割り当てる必要があるときはいつでも、その変数をオプションにすることができるというスウィフトのルールに注意する必要があります。上のステートメントでは、クラス内でselfを使ってiの値をjに代入しようとしています。コンパイラがその行をコンパイルするときに、クラスのオブジェクトが作成されず、使用している自己がnilなので、コンパイラがエラーを投げているのです(上記と同じ理由でselfを使わなくてもエラーを投げます) 。

それはあなたの作業コードに問題を引き起こしていない理由:あなたがその変数を呼び出すとき

lazy var j:Int = self.i 

私は怠け者VARに値以上述べたように割り当てられています。あなたはその変数をクラスの外にどのように呼びますか?もちろん、オブジェクトを作成します。あなたがオブジェクトの助けを借りてそれを呼び出すときには、「自己」は同じオブジェクトを指し、自己は何の問題も生じないでしょう。それが宣言されているときに、データ型を指定する必要が怠惰なVARを宣言しながら、あなたが3つの事

  • を理解する必要が短い二つのことが
  • 怠惰VARが割り当てられていない、それは時に付与されて

  • と呼ばれ、あなたのクラスここ
+0

で私は怠惰なVARを宣言する際にデータ型が必要とされているとは思いません。 '' lazy var name = "some name"というコードは問題なくコンパイルします。 –

+2

ハードコードされた値を遅延型の変数に渡す場合、データ型のコンパイラはその型を理解するでしょう。は働いている。あなたのコードでは、自分自身の助けを借りてiの値を割り当てることを試みている値を直接割り当てません。コンパイラは自己、私と私のデータ型を知らない。だからこそ、データ型は、そのような場合や、あなたが怠惰なvarのクロージャを書く場合に必要です。 –

0

のインスタンス(オブジェクト)なしでインスタンスVARを呼び出すことはできませんと、ビューコントロールで遅延初期化の例です。

注()LER終了

lazy var myViewController : MyViewController? = { 
    let storyboard: UIStoryboard = UIStoryboard(name: "MyVC", bundle: nil) 
    return storyboard.instantiateViewController(withIdentifier: "MyAccount") as? MyViewController 
}() 
関連する問題