lazyプロパティはSwiftでは初回アクセス時にのみ計算されます。これは、すぐには必要ないリソースを多く消費するオブジェクト(例:重い計算やネットワークのダウンロード)でよく使用されます。lazyキーワードを使って宣言されます:
class DataFetcher { lazy var data: Data = self.loadData() func loadData() -> Data { /* … */ } }
特徴と注意点:
lazyプロパティは変数(var)にのみ許可され、定数(let)には使用できません。lazyプロパティは機能しません。lazy値は各インスタンスごとにキャッシュされます。質問:「クラスのインスタンスを初期化するときにlazyプロパティの値は作成されますか?」
回答:いいえ、値はプロパティへの最初のアクセス時に計算され、初期化時には計算されません。
class Expensive { init() { print("init") } } class Example { lazy var heavy = Expensive() } let foo = Example() // 何も出力しない _ = foo.heavy // 今、「init」
ストーリー
二つのプラットフォームのプロジェクトで画像キャッシュを保持するためにlazy配列(lazy var)が使用されていました。同時に複数スレッドからアクセスすると競合が発生し、lazy varをミューテックスで囲みましたが、lazyの特性を忘れたため、アプリケーションがクラッシュしました。
ストーリー
若い開発者が重い計算をキャッシュするためにlazy letを宣言しようとしました。コードはコンパイルされず、lazyはvarにのみ許可されるため、アーキテクチャを見直さなければなりませんでした。
ストーリー
開発者は初期化時にclosure内でselfをキャプチャしたlazyプロパティを宣言しました。これにより循環参照が発生し、オブジェクトは画面から消えた後も解放されませんでした。