見出し画像

Xcode13.1 / iOS15.0でもNavigationLinkでの遷移先Viewの遅延評価はされない話

タイトルの通りなのですが、
また新たな学びを得たので、自分の気づきを書きます。

課題は何か

2021年のiOSDCのfukayaさんの発表で、
「NavigationLink.destinationに設定したViewはNavigationLinkが読み込まれると同時に初期化されてしまう」
という課題を知りました。

https://speakerdeck.com/akifumifukaya/iosdc21?slide=34 より引用

これによるデメリットは、スライドにもあるように、
「多くの不要なインスタンスが生成されてしまう」
ことだと思います。

その解決策として、
LazyViewを導入し、遅延評価する(遷移先のViewに遷移したタイミングで初期化されるようにする)
という方法が紹介されていました。

実際に確認してみる

実際に確認してみました。

確認環境は以下の通りです。

【Xcode】13.1
【iOS】15.0
【MacOS】Big Sur バージョン11.4

実験のための実装したものは、以下の通りです。
それぞれの初期化タイミングで、コンソールに文字が出力されるように実装します。

遷移前のView -> コード上ではContentView(NavigationLinkを使用してSecondViewへ遷移するように)
遷移後のView -> コード上ではSecondView
遷移後のViewで使用されるViewModel -> コード上ではSecondViewModel

LazyView導入前

ご覧の通りですが、
ContentViewが表示されたタイミングで、コンソールにばっちり3行表示されています。

つまりContentViewが初期化されたタイミングで、SecondViewとSecondViewの初期化時に初期化されるSecondViewModelも初期化されています。

SwiftUI Navigation Links and the Common Pitfalls Faced」の記事に、
「Update: As of Xcode 11.4.1, iOS 13.4.1, Apple has fixed this issue.」と記載があったのですが、ご覧の通りまだ直っていないようです。😢

コメントでも何人か言及してましたね。👀

LazyView導入後

では早速LazyViewを導入してみます。

その結果がこちら。
ContentView表示時にコンソールに出力されているのは、「ContentViewが初期化された」の1行のみ!🤗

SecondViewとSecondViewModelの初期化はされていないことがわかりました。

一応動くコードはGitHubにあげています。

おわりに

結論何が言いたかったかというと、タイトルの通り
「Xcode13.1 / iOS15.0でもNavigationLinkでの遷移先Viewの遅延評価はされない」
ということでした。

ちなみに「SwiftUI Navigation Links and the Common Pitfalls Faced」の内容自体はとても参考になると思っています。

でも記事で書いてることを盲目的に信じずに、
ちゃんと自分で動かしてみた方が良いということを実感したので、書いてみました。

おわり。

いいなと思ったら応援しよう!