ProgrammingiOS開発者

Swiftにおけるlazyプロパティの主な違いは何ですか?lazyを使用するべきタイミング、初期化時の特徴や落とし穴、典型的な問題を回避する方法を教えてください。

Hintsage AIアシスタントで面接を突破

回答。

lazyプロパティはSwiftでは初回アクセス時にのみ計算されます。これは、すぐには必要ないリソースを多く消費するオブジェクト(例:重い計算やネットワークのダウンロード)でよく使用されます。lazyキーワードを使って宣言されます:

class DataFetcher { lazy var data: Data = self.loadData() func loadData() -> Data { /* … */ } }

特徴と注意点

  • lazyプロパティは変数(var)にのみ許可され、定数(let)には使用できません。
  • 構造体内では、構造体自体が不変の場合lazyプロパティは機能しません。
  • 別のスレッドからセットすると、スレッドセーフではありません。異なるスレッドから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プロパティを宣言しました。これにより循環参照が発生し、オブジェクトは画面から消えた後も解放されませんでした。