web-dev-qa-db-ja.com

Swiftの怠惰な変数は複数回計算されていますか?

Swiftの怠惰な変数は複数回計算されていますか?私はそれらが以下を置き換えたという印象を受けました:

if (instanceVariable) {
    return instanceVariable;
}

// set up variable that has not been initialized

Objective-Cのパラダイム(遅延インスタンス化)。

それは彼らがしていることですか?基本的に、アプリが最初に変数を要求したときに1回だけ呼び出され、計算されたものを返すだけですか?

それとも、通常の計算プロパティのように毎回呼び出されますか?

私が尋ねる理由は、基本的にSwiftに、他のインスタンス変数にアクセスできる計算されたプロパティが必要だからです。「fullName」という変数があり、firstNameとを連結するだけだとします。 lastName。Swiftでこれを行うにはどうすればよいですか?通常の計算変数(遅延なし)では他のインスタンス変数にアクセスできないため、遅延変数が唯一の方法のようです。

だから基本的に:

Swiftの怠惰な変数は複数回呼び出されますか?その場合、インスタンス変数にアクセスできる計算変数を作成するにはどうすればよいですか?そうでない場合は、変数を1回だけ計算する必要がありますパフォーマンス上の理由、これを行うにはどうすればよいですか?

28
Doug Smith

lazy varsは、初めて使用するときに1回だけ計算されます。その後、それらは通常の変数のようになります。

これは遊び場で簡単にテストできます。

class LazyExample {
    var firstName = "John"
    var lastName = "Smith"
    lazy var lazyFullName : String = {
        [unowned self] in
        return "\(self.firstName) \(self.lastName)"
    }()
}

let lazyInstance = LazyExample()

println(lazyInstance.lazyFullName)
// John Smith

lazyInstance.firstName = "Jane"

println(lazyInstance.lazyFullName)
// John Smith

lazyInstance.lazyFullName = "???"

println(lazyInstance.lazyFullName)
// ???

後で再計算する場合は、Objective-Cで行ったのと同じように、計算されたプロパティを使用します(コストがかかる場合はバッキング変数を使用します)。

23
Aaron Brager

いいえ、レイジープロパティは一度だけ初期化されます。新しい値を設定するか、(オプションのプロパティの場合)nilにリセットすると、遅延初期化子not再び呼び出されます。

必要なのは計算されたプロパティだと思います。保存されたプロパティに支えられていないため、初期化には関与しません。そのため、他のインスタンスプロパティを参照できます。

「通常の計算変数(遅延なし)は他のインスタンス変数にアクセスできない」と言うのはなぜですか?

6
Antonio

他のすべての答えは正しいです、私はそれを追加したいと思いますApplelazy変数と並行性について警告します:

レイジー修飾子でマークされたプロパティが複数のスレッドによって同時にアクセスされ、プロパティがまだ初期化されていない場合、プロパティが1回だけ初期化されるという保証はありません。

1
Balázs Vincze

怠惰な変数は一度しか計算できないという回答は真実ではありませんhttps://docs.Swift.org/Swift-book/LanguageGuide/Properties.html のドキュメントから、次のように記載されています。

レイジー修飾子でマークされたプロパティが複数のスレッドによって同時にアクセスされ、プロパティがまだ初期化されていない場合、プロパティが1回だけ初期化されるという保証はありません。

また、このトークをご覧ください: https://developer.Apple.com/videos/play/wwdc2016/720/ 。 17:00頃、次の画面が表示されます。

enter image description here

その話はあなたにマルチスレッドについてのより多くの洞察を与えます、私はあなたがそれを見ることをお勧めします!

1
J. Doe