ナビゲーショングラフ内でviewModel()を使用した場合、取得できるViewModelは独自のViewModelStoreOwnerに紐づいている。ActivityやFragmentに紐づいたものは取得できない。

# まとめ
- ナビゲーショングラフ内で`viewModel()`を使用した場合、取得できる`ViewModel`は`Activity`や`Fragment`のそれとは別の、独自の`ViewModelStoreOwner`に紐づいています。
- そのナビゲーションの乗っている`Activity`や`Fragment`に紐づいたものは取得できません。
- 特に`AndroidView`と組み合わせて使用した場合、`Activity`や`Fragment`のライフライクルに紐づいたものを取得できることを無意識のうちに期待しがちなので注意。
- ナビゲーショングラフはデスティネーション毎(パス毎)に独立した`ViewModelStoreOwner`を持ちます。


## つまりこういうこと
以下のような`ViewModel`クラスと`Activity`があった時に、

```SampleViewModel.kt
class SampleViewModel : ViewModel() {

    // 新しいインスタンスができるたびにユニークなIDを振ります。
    private val id = UUID.randomUUID()

    fun getId() = id
}
```
```MainActivity.kt
class MainActivity : ComponentActivity() {

    private val viewModel: SampleViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            Log.i(TAG, "setContent viewModel id : " + viewModel.getId())
            MakeTransparentAppTheme {
                MakeNavigation()
            }
        }
    }

}


@SuppressLint("CoroutineCreationDuringComposition")
@Composable
private fun MakeNavigation(viewModel: SampleViewModel = viewModel()) {
    Log.i(TAG, "MakeNavigation viewModel id : " + viewModel.getId())

    val navController = rememberNavController()

    NavHost(navController = navController, startDestination = "home") {
        composable("home") {
            val viewModel1: SampleViewModel = viewModel()
            Log.i(TAG, "NavStackEntry Home1 viewModel id : " + viewModel1.getId())
            Home1()
        }

        composable("home2") {
            val viewModel2: SampleViewModel = viewModel()
            Log.i(TAG, "NavStackEntry Home1 viewModel id : " + viewModel2.getId())
            Home2()
        }
    }


    rememberCoroutineScope().launch {
        delay(1000)
        Log.i(TAG, "navigate to Home2")
        navController.navigate("home2")
    }

}

@Composable
fun Home1(viewModel: SampleViewModel = viewModel()) {
    Log.i(TAG, "Home1 viewModel id : " + viewModel.getId())
    Home2()
}


@Composable
fun Home2(viewModel: SampleViewModel = viewModel()) {
    Log.i(TAG, "Home2 viewModel id : " + viewModel.getId())
    Home3()
}


@Composable
fun Home3(viewModel: SampleViewModel = viewModel()) {
    Log.i(TAG, "Home3 viewModel id : " + viewModel.getId())
}
```


Logcatはこのようになります。(抜粋)

```zsh
setContent viewModel id : 4971f3d3-bfc0-4775-b8b0-7180ab8759d1　<-- ActivityのViewModelStoreOwnerに紐づいているViewModel
MakeNavigation viewModel id : 4971f3d3-bfc0-4775-b8b0-7180ab8759d1　<-- ActivityのViewModelStoreOwnerに紐づいているViewModel
// ここから"home"パスを表示
NavHost is called
NavStackEntry Home1 viewModel id : aaebbc8a-759c-4885-8524-ffb07136c917  <-- (Activityではなく)独自のViewModelStoreOwnerに紐づいているViewModel="home"パスのNavStackEntryのViewModelStoreOwnerに紐づいているViewModel
Home1 viewModel id : aaebbc8a-759c-4885-8524-ffb07136c917  <-- "home"パスのNavStackEntryと同じ独自のViewModelStoreOwnerに紐づいているViewModel
Home2 viewModel id : aaebbc8a-759c-4885-8524-ffb07136c917  <-- "home"パスのNavStackEntryと同じ独自のViewModelStoreOwnerに紐づいているViewModel
Home3 viewModel id : aaebbc8a-759c-4885-8524-ffb07136c917  <-- "home"パスのNavStackEntryと同じ独自のViewModelStoreOwnerに紐づいているViewModel
// ここから"home2"パスへ移動処理
navigate to Home2
NavStackEntry Home1 viewModel id : aaebbc8a-759c-4885-8524-ffb07136c917  <-- "home"パスのNavStackEntryと同じ独自のViewModelStoreOwnerに紐づいているViewModel="home2"パスのNavStackEntryのViewModelStoreOwnerに紐づいているViewModel
NavStackEntry Home2 viewModel id : e38c3070-860a-4f40-bdca-37b6b65ec999  <-- Activityとも"home"のパスの時とも違う独自のViewModelStoreOwnerに紐づいているViewModel
Home2 viewModel id : e38c3070-860a-4f40-bdca-37b6b65ec999  <-- "home2"パスのNavStackEntryと同じ独自のViewModelStoreOwnerに紐づいているViewModel
Home3 viewModel id : e38c3070-860a-4f40-bdca-37b6b65ec999  <-- "home2"パスのNavStackEntryと同じ独自のViewModelStoreOwnerに紐づいているViewModel
NavStackEntry Home2 viewModel id : e38c3070-860a-4f40-bdca-37b6b65ec999  <-- "home2"パスのNavStackEntryと同じ独自のViewModelStoreOwnerに紐づいているViewModel
```

# 細かく
上記の通りで、またナビゲーションが画面から画面への遷移を表現するために使われることが多いことを考えれば納得の動きです。
ですが最初この動きを把握しておらず、どうなっているのかコードを追ってみて理解しました。
せっかくコードを追ったので備忘録として要点をかいつまんでですが残しておきます。

## 環境
- Jetpack Compose ライブラリ : v1.2.0


## コンポーズ可能なメソッド内でviewModel()を呼んだ時何が起きるのか

コンポーズ可能なメソッド内でviewModel()を呼んだ時は以下のようなメソッドが呼ばれています。
(コード内のXXXで始まるコメント文は私が足したものです。)

```ViewModel.kt
@Suppress("MissingJvmstatic")
@Composable
public inline fun <reified VM : ViewModel> viewModel(
    viewModelStoreOwner: ViewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
        "No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
    }, // XXX 引数なしでviewModel()を呼ぶと、viewModelStoreOwnerとして
       // LocalViewModelStoreOwner.currentが(Nullでなければ)使われます。
    key: String? = null,
    factory: ViewModelProvider.Factory? = null,
    extras: CreationExtras = if (viewModelStoreOwner is HasDefaultViewModelProviderFactory) {
        viewModelStoreOwner.defaultViewModelCreationExtras
    } else {
        CreationExtras.Empty
    }
): VM = viewModel(VM::class.java, viewModelStoreOwner, key, factory, extras)
```

第一引数の、

```kotlin
    viewModelStoreOwner: ViewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
        "No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
    }
```

のあたりで、**`viewModelStoreOwner`として`LocalViewModelStoreOwner.current`が使われています。(…①)**



## ナビゲーショングラフ内で何をしているか
ちょっと話は飛びますが、次はコンポーズ可能なメソッドの中で`NavHost`メソッドを呼んだ時の動きについて追います。
コンポーズ可能なメソッドの中で`NavHost`メソッドを呼んだ時は以下のような定義のメソッドが呼ばれます。

```NavHost.kt
@Composable
public fun NavHost(
    navController: NavHostController,
    startDestination: String,
    modifier: Modifier = Modifier,
    route: String? = null,
    builder: NavGraphBuilder.() -> Unit
) {
    NavHost(
        navController,
        remember(route, startDestination, builder) {
            navController.createGraph(startDestination, route, builder)
        },
        modifier
    )
}
```

この中で呼ばれている`NavHost`メソッドは以下のような定義になっています。
(コード内のXXXで始まる日本語のコメント文は私が足したものです。)

```NavHost.kt
@Composable
public fun NavHost(
    navController: NavHostController,
    graph: NavGraph,
    modifier: Modifier = Modifier
) {
    val lifecycleOwner = LocalLifecycleOwner.current
    val viewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
        "NavHost requires a ViewModelStoreOwner to be provided via LocalViewModelStoreOwner"
    } // XXX ここでもviewModelStoreOwnerとしてLocalViewModelStoreOwner.currentが使われています。

    val onBackPressedDispatcherOwner = LocalOnBackPressedDispatcherOwner.current
    val onBackPressedDispatcher = onBackPressedDispatcherOwner?.onBackPressedDispatcher

    // Setup the navController with proper owners
    navController.setLifecycleOwner(lifecycleOwner)
    navController.setViewModelStore(viewModelStoreOwner.viewModelStore) // XXX navControllerのViewModelStoreは
                                                                        // LocalViewModelStoreOwner.current.viewModelStoreになりました。

    // (中略)

    val visibleEntries by remember(navController.visibleEntries) {
        navController.visibleEntries.map {
            it.filter {
                    entry -> entry.destination.navigatorName == ComposeNavigator.NAME
            }
        }
    }.collectAsState(emptyList())  // XXX navController.visibleEntriesの値(のうちCompose用のもの)をStateにして
                                   // visibleEntriesとして持ちます。




    val backStackEntry = visibleEntries.lastOrNull() // XXX visibleEntriesの最後のアイテムを
                                                     // backStackEntryとしています。


    var initialCrossfade by remember { mutableStateOf(true) }
    if (backStackEntry != null) {
        // while in the scope of the composable, we provide the navBackStackEntry as the
        // ViewModelStoreOwner and LifecycleOwner
        Crossfade(backStackEntry.id, modifier) {
            val lastEntry = visibleEntries.last { entry ->
                it == entry.id
            }// XXX visibleEntriesの最後のアイテムを
             // 今度はlastEntryとしています。

            // We are disposing on a Unit as we only want to dispose when the CrossFade completes
            DisposableEffect(Unit) {
                if (initialCrossfade) {
                    // There's no animation for the initial crossfade,
                    // so we can instantly mark the transition as complete
                    visibleEntries.forEach { entry ->
                        composeNavigator.onTransitionComplete(entry)
                    }
                    initialCrossfade = false
                }
                onDispose {
                    visibleEntries.forEach { entry ->
                        composeNavigator.onTransitionComplete(entry)
                    }
                }
            }

            lastEntry.LocalOwnersProvider(saveableStateHolder) {
                (lastEntry.destination as ComposeNavigator.Destination).content(lastEntry)
            } // XXX lastEntry#.LocalOwnersProviderメソッドを呼んでいます。
        }
    }


    // (以下略)

}
```

ここでの処理の大事なところは、最後の
```kotlin
            lastEntry.LocalOwnersProvider(saveableStateHolder) {
                (lastEntry.destination as ComposeNavigator.Destination).content(lastEntry)
            } // XXX lastEntry#.LocalOwnersProviderメソッドを呼んでいます。
```

の`lastEntry.LocalOwnersProvider`部分です。
この`lastEntry`は少し前の

```kotlin
            val lastEntry = visibleEntries.last { entry ->
                it == entry.id
            }// XXX visibleEntriesの最後のアイテムを
             // 今度はlastEntryとしています。
```
より`visibleEntries`の最後のアイテムになっており、

`visibleEntries`はさらに少し前の方(`(中略)`の直後)の

```kotlin
    val visibleEntries by remember(navController.visibleEntries) {
        navController.visibleEntries.map {
            it.filter {
                    entry -> entry.destination.navigatorName == ComposeNavigator.NAME
            }
        }
    }.collectAsState(emptyList())  // XXX navController.visibleEntriesの値(のうちCompose用のもの)をStateにして
                                   // visibleEntriesとして持ちます。
```

より、`navController.visibleEntriesの値(のうちCompose用のもの)`を`State`としたものです。

ちなみに`navController.visibleEntries`は`NavBackStackEntry`のリストのStateFlowで、現在表示しているパスの画面やバックスタックに積まれているものが変わると変化します。
→つまり`NavController.navigate`や`NavController.popBackStack`メソッドが呼ばれると変化します。



よって、`navController.visibleEntries`の(最後の?)値が変わるたびに、自動的に、先ほど「ここでの処理の大事なところ」とした
```kotlin
            lastEntry.LocalOwnersProvider(saveableStateHolder) {
                (lastEntry.destination as ComposeNavigator.Destination).content(lastEntry)
            } // XXX lastEntry#.LocalOwnersProviderメソッドを呼んでいます。
```
が呼ばれます。



さて、では`lastEntry.LocalOwnersProvider`メソッドが何をしているかですが、このメソッドの定義は以下です。
※ちなみに`NavBackStackEntry`クラスは`ViewModelStoreOwner`も実装しています。

```NavBackStackEntryProvider.kt
@Composable
public fun NavBackStackEntry.LocalOwnersProvider(
    saveableStateHolder: SaveableStateHolder,
    content: @Composable () -> Unit
) {
    CompositionLocalProvider(
        LocalViewModelStoreOwner provides this,
        LocalLifecycleOwner provides this,
        LocalSavedStateRegistryOwner provides this
    ) {
        saveableStateHolder.SaveableStateProvider(content)
    }
}
```

最初に注目すべきは`CompositionLocalProvider`メソッドの第一引数の`LocalViewModelStoreOwner provides this`です。
こちらのメソッドの定義は
```LocalViewModelStoreOwner.kt
public object LocalViewModelStoreOwner {
    private val LocalViewModelStoreOwner =
        compositionLocalOf<ViewModelStoreOwner?> { null }

    /**
     * Returns current composition local value for the owner or `null` if one has not
     * been provided nor is one available via [ViewTreeViewModelStoreOwner.get] on the
     * current [LocalView].
     */
    public val current: ViewModelStoreOwner?
        @Composable
        get() = LocalViewModelStoreOwner.current
            ?: ViewTreeViewModelStoreOwner.get(LocalView.current)

    /**
     * Associates a [LocalViewModelStoreOwner] key to a value in a call to
     * [CompositionLocalProvider].
     */
    public infix fun provides(viewModelStoreOwner: ViewModelStoreOwner):
        ProvidedValue<ViewModelStoreOwner?> {
            return LocalViewModelStoreOwner.provides(viewModelStoreOwner)
        }
}
```

の最後の`public infix fun provides`メソッドです。(ちなみに、余談&捕捉ですが`infix`メソッドは呼び出し時にメソッド名と引数の間のカッコ`(` `)`を省略して書けるメソッドです。)

こちらは何をしているかというと引数で渡された`viewModelStoreOwner`を引数にして、`LocalViewModelStoreOwner.provides`メソッドを呼んでいます。この、「引数で渡された`viewMOdelStoreOwner`」とは今回の場合`lastEntry`(＝「現在表示している画面=`NavBackStackEntry`)」です。
`LocalViewModelStoreOwner.provides`メソッドの定義は以下で

```CompositionLocal.kt
    @Suppress("UNCHECKED_CAST")
    infix fun provides(value: T) = ProvidedValue(this, value, true)
```


`ProvidedValue`クラスの定義は以下です。
要するに「第1フィールドとして`LocalViewModelStoreOwner`、第2フィールドとして現在表示している`NavBackStackEntry`が入っているdataクラスのようなもの」と覚えておけばいいと思います。

```Composer.kt
class ProvidedValue<T> internal constructor(
    val compositionLocal: CompositionLocal<T>,
    val value: T,
    val canOverride: Boolean
)
```

さて、`public fun NavBackStackEntry.LocalOwnersProvider`の処理の中身追いに戻ります。ここまでで

```NavBackStackEntryProvider.kt
@Composable
public fun NavBackStackEntry.LocalOwnersProvider(
    saveableStateHolder: SaveableStateHolder,
    content: @Composable () -> Unit
) {
    CompositionLocalProvider(
        LocalViewModelStoreOwner provides this,
        LocalLifecycleOwner provides this,
        LocalSavedStateRegistryOwner provides this
    ) {
        saveableStateHolder.SaveableStateProvider(content)
    }
}
```
の`CompositionLocalProvider`メソッドの第一引数の`LocalViewModelStoreOwner provides this`が「第1フィールドとして`LocalViewModelStoreOwner`、第2フィールドとして現在表示している`NavBackStackEntry`が入っているdataクラスのようなもの」だということが分かりました。
次は`CompositionLocalProvider`メソッド自体の定義を確認します。定義は以下です。

```CompositionLocal.kt
/**
 * [CompositionLocalProvider] binds values to [ProvidableCompositionLocal] keys. Reading the
 * [CompositionLocal] using [CompositionLocal.current] will return the value provided in
 * [CompositionLocalProvider]'s [values] parameter for all composable functions called directly
 * or indirectly in the [content] lambda.
 *
 * @sample androidx.compose.runtime.samples.compositionLocalProvider
 *
 * @see CompositionLocal
 * @see compositionLocalOf
 * @see staticCompositionLocalOf
 */
@Composable
@OptIn(InternalComposeApi::class)
fun CompositionLocalProvider(vararg values: ProvidedValue<*>, content: @Composable () -> Unit) {
    currentComposer.startProviders(values)
    content()
    currentComposer.endProviders()
}
```

メソッドのjavadocにあるように、
```txt
CompositionLocalProvider binds values to ProvidableCompositionLocal keys. 
Reading the CompositionLocal using CompositionLocal.current will return the value 
provided in CompositionLocalProvider's values parameter for all composable functions called directly or indirectly 
in the content lambda.
```
こちらのメソッドを使用すると(引数の`ProvidedValue`の配列`values`の1要素の第1フィールド)`CompositionLocal`の`CompositionLocal.current`を呼んだ時の値を(第2フィールドの)`value`に変更。した状態で引数`content‘としてわたってきた`@Composable () -> Unit`メソッドを呼んでくれます。


つまり、今見ているシチュエーションでは、「第1フィールドとして`LocalViewModelStoreOwner`、第2フィールドとして現在表示している`NavBackStackEntry`が入っている」ものが渡ってきている状況を見ていたので、**このメソッドによりこの`CompositionLocalProvider`の引数`content`は`LocalViewModelStoreOwner.current`が`NavBackStackEntry`になる状態で実行されることが分かります。(…②)**



今見ているシチュエーションでは、`content`は前述の呼び出し側で渡している以下のラムダ式です。

```NavBackStackEntryProvider.kt
{
        saveableStateHolder.SaveableStateProvider(content)
    }
```

更に、`saveableStateHolder.SaveableStateProvider(content)`の`content`はこれまた前述の`NavBackStackEntry.LocalOwnersProvider`メソッドの第2引数なのでこの場合以下のラムダ式です。

```NavHost.kt
 {
                (lastEntry.destination as ComposeNavigator.Destination).content(lastEntry)
            }
```

このラムダ式に出てくる、`ComposeNavigator.Destination.content`の定義は、

```ComposeNavigationr.kt
    /**
     * NavDestination specific to [ComposeNavigator]
     */
    @NavDestination.ClassType(Composable::class)
    public class Destination(
        navigator: ComposeNavigator,
        internal val content: @Composable (NavBackStackEntry) -> Unit
    ) : NavDestination(navigator)

```
となっています。(…③)

さて、ここで、最初にアプリケーション側から`NavHost`メソッドを呼ぶ時にナビゲーショングラフを作成するときに使用する`NavGraphBuilder.composable`メソッドの定義を見てみます。

```NavGraphBuilder.kt
public fun NavGraphBuilder.composable(
    route: String,
    arguments: List<NamedNavArgument> = emptyList(),
    deepLinks: List<NavDeepLink> = emptyList(),
    content: @Composable (NavBackStackEntry) -> Unit
) {
    addDestination(
        ComposeNavigator.Destination(provider[ComposeNavigator::class], content).apply {
            this.route = route
            arguments.forEach { (argumentName, argument) ->
                addArgument(argumentName, argument)
            }
            deepLinks.forEach { deepLink ->
                addDeepLink(deepLink)
            }
        }
    )
}

```

メソッド内の処理の2行目`ComposeNavigator.Destination(provider[ComposeNavigator::class], content).apply {`より、`ComposeNavigator.Destination.content`には`NavGraphBuilder.composable`メソッドを呼ぶときに渡すラムダ式部分が来ることが分かりました。(…④)

③、④より

```NavBackStackEntryProvider.kt
{
        saveableStateHolder.SaveableStateProvider(content)
    }
```
で`saveableStateHolder.SaveableStateProvider`に渡している`content`は「アプリケーション側で`NavHost`メソッドを呼ぶときに渡すラムダ式の中で`NavGraphBuilder.composable`メソッドを呼んでいるところで渡すラムダ式部分を、現在表示中の`NavBackStackEntry`を引数として使用して呼び出す」内容なことが分かりました。

ここで`saveableStateHolder.SaveableStateProvider`の方の処理を確認すると、以下のようになっています。

```NavBackStackEntryProvider.kt
@Composable
private fun SaveableStateHolder.SaveableStateProvider(content: @Composable () -> Unit) {
    val viewModel = viewModel<BackStackEntryIdViewModel>()
    viewModel.saveableStateHolder = this
    SaveableStateProvider(viewModel.id, content)
    DisposableEffect(viewModel) {
        onDispose {
            viewModel.saveableStateHolder = null
        }
    }
}

```

ここで見るべきなのは真ん中あたりにある`SaveableStateProvider(viewModel.id, content)`の処理です。このメソッドの定義は`interface SaveableStateHolder`にあり、実装は`SaveableStateHolderImpl`クラスにあって以下のようになっています。

```SaveableStateHolder.kt
    @Composable
    override fun SaveableStateProvider(key: Any, content: @Composable () -> Unit) {
        ReusableContent(key) {
            val registryHolder = remember {
                require(parentSaveableStateRegistry?.canBeSaved(key) ?: true) {
                    "Type of the key $key is not supported. On Android you can only use types " +
                        "which can be stored inside the Bundle."
                }
                RegistryHolder(key)
            }
            CompositionLocalProvider(
                LocalSaveableStateRegistry provides registryHolder.registry,
                content = content
            )
 
            // (以下略)


        }
    }
```

上の、

```kotlin
            CompositionLocalProvider(
                LocalSaveableStateRegistry provides registryHolder.registry,
                content = content
            )
```

で、`saveableStateHolder.SaveableStateProvider`に渡している`content`==「アプリケーション側で`NavHost`メソッドを呼ぶときに渡すラムダ式の中で`NavGraphBuilder.composable`メソッドを呼んでいるところで渡すラムダ式部分を、現在表示中の`NavBackStackEntry`を引数として使用して呼び出す」を第2引数(=`content`)として、`LocalSaveableStateRegistry.current`を上書きする`CompositionLocalProvider`を呼んでいます。

さて、ここで、「`LocalSaveableStateRegistry.current`を上書きする」といっていますが、そもそも`SaveableStateProvider(viewModel.id, content)`自体、`LocalViewModelStoreOwner.current`や`LocalViewModelStoreOwner.current`,`LocalSavedStateRegistryOwner.current`を上書きする`CompositionLocalProvider`の`content`として呼び出されるものでした。
ゆえに`SaveableStateProvider(viewModel.id, content)`の`CompositionLocalProvider`で「`LocalSaveableStateRegistry.current`を上書き」される前の他の`current`は上書きされたもの、そしてそれは②より`LocalViewModelStoreOwner.current`は`NavBackStackEntry`です。

つまり、**「アプリケーション側で`NavHost`メソッドを呼ぶときに渡すラムダ式の中で`NavGraphBuilder.composable`メソッドを呼んでいるところで渡すラムダ式」部分は、`LocalViewModelStoreOwner.current`が`NavBackStackEntry`の状態で呼びだされます。(…⑤)**


## ということにより
[コンポーズ可能なメソッド内でviewModel()を呼んだ時何が起きるのか](#コンポーズ可能なメソッド内でviewModel()を呼んだ時何が起きるのか)の結論①と、[ナビゲーショングラフ内で何をしているか](#ナビゲーショングラフ内で何をしているか)の結論⑤より、
**コンポーズ可能なメソッド内で`viewModel()`を呼んだ時は`VideModelStoreOwner`として`LocalViewModelStoreOwner.current`が使われ、`LocalViewModelStoreOwner.current`はナビゲーショングラフ内では、今表示中の`NavBackStackEntry`(≒今表示中のパスの画面)になる**ことが分かります。

つまり、ナビゲーショングラフはデスティネーション毎(パス毎)に独立した`ViewModelStoreOwner`を持ち、`viewModel()`を呼んだ時はパス毎に異なる`ViewModel`のインスタンスが取得出来て、それらはナビゲーショングラフの載っている`Activity`や`Fragment`のものとは別のインスタンスです。


## 注意

※ 2022/10/9 追記 : 公開当初下の内容を書いてしまっていましたが、間違っています。
ここまでの議論の通り`NavGraphBuilder.composable`メソッドのラムダ式の中は`NavBackStackEntry`に紐づいた`ViewModel`が取得できます。

「注意」セクションを本編部分の執筆を書く前に書いてあったのですが、この記事を書き始めた時点ではそもそもサンプルコードが間違っていて、それにこじつけるような内容になっていました。本編執筆の過程で理解も深まり、以前とは大筋の結論が変わったりしたのですが「注意」の章に関して最後に見直すこともほぼせず最初に書いたものをそのまま公開してしまっていました。。。


現在の理解としては、この記事の話題について、特段注意すべきことはないと考えています。


一応、以前のバージョンのサンプルコードのスニペットとともに残しておきます。

- ~~以下の、~~
```kotlin
    NavHost(navController = navController, startDestination = "home") {
        composable("home") {
            Log.i(TAG, "NavStackEntry Home1 viewModel id : " + viewModel.getId())
            Home1()
        }

        composable("home2") {
            Log.i(TAG, "NavStackEntry Home2 viewModel id : " + viewModel.getId())
            Home2()
        }
    }
```
~~`Log.i(TAG, "NavStackEntry Home1 viewModel id : " + viewModel.getId())`や`Log.i(TAG, "NavStackEntry Home2 viewModel id : " + viewModel.getId())`をしている場所は、引数に`NavBackStackEntry`が渡ってきているラムダメソッドの場所だが、ここではまだ`LocalViewModelStoreOwner.current`は`NavBackStackEntry`でない。その中で画面を作成するために呼ばれた`Home1()`や`Home2()`以降が`LocalViewModelStoreOwner.current`=`NavBackStackEntry`。~~


## 感想
- 書き終わった勢いで公開せず、ちゃんと補足の章まで含めてすべてきちんと見直すべきですね。。当たり前ですが。。。