Created
May 20, 2024 00:38
-
-
Save ynagatomo/50a290aee280203823221a75108976f9 to your computer and use it in GitHub Desktop.
This sample shows Observable object instances with `@Observable and @State` are created many times when a view that has the property is evaluated. So avoid heavy initializations on the Observable classes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ObservableTwiceInitProblemTestApp.swift | |
// ObservableTwiceInitProblemTest | |
// | |
// Created by Yasuhito Nagatomo on 2024/05/20. | |
// | |
// Modified christianselig/sample-view-model-init.swift | |
// https://gist.github.com/christianselig/d88b1a4d1989b973689ae62d4691162f | |
// | |
// This sample shows Observable object instances with `@Observable and @State` | |
// are created many times when a view that has the property is evaluated. | |
// So avoid heavy initializations on the Observable classes. | |
import SwiftUI | |
@main | |
struct WindowPresentationFunApp: App { | |
@State var appState = AppState() | |
var body: some Scene { | |
WindowGroup { | |
InitialView(appState: appState) | |
} | |
} | |
} | |
struct InitialView: View { | |
let appState: AppState | |
@State private var showing = false | |
var body: some View { | |
Button(action: { showing.toggle() }, label: { Text("Tap Me")}) | |
.sheet(isPresented: $showing) { | |
RootView(appState: appState) | |
} | |
} | |
} | |
struct RootView: View { | |
let appState: AppState | |
var body: some View { | |
VStack { | |
Text("Swipe down to close").padding() | |
SpecialView() | |
Button(action: { appState.show.toggle() }) { | |
Text("Change the show flag").padding() | |
} | |
Text("Show flag: " + (appState.show ? "True" : "False")).padding() | |
} | |
} | |
} | |
struct SpecialView: View { | |
@State private var viewModel = ViewModel() | |
var body: some View { | |
let _ = print("SpecialView will be evaluated.") | |
Text("Special stuff, VM's MyID: \(viewModel.myID)") | |
} | |
} | |
@Observable class AppState { | |
var show: Bool = false | |
} | |
@Observable class ViewModel { | |
let myID = UUID() | |
// This cannot be `lazy` when using @Observable | |
let attribute1: Int = { | |
print("Heavy Calculation #1 ...") | |
return 0 | |
}() | |
init() { | |
print("✅ View model was inited ID: \(myID)") | |
} | |
deinit { | |
print("❌ View model was deinited ID: \(myID)") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment