Procházet zdrojové kódy

Refactor Treatments State cleanup logic to onDisappear to prevent crash during deinit

Deniz Cengiz před 1 rokem
rodič
revize
f7c0e4f2d2

+ 24 - 18
Trio/Sources/Modules/Home/View/HomeRootView.swift

@@ -1042,7 +1042,7 @@ extension Home {
                     NavigationStack { DataTable.RootView(resolver: resolver) }
                         .tabItem { Label("History", systemImage: historySFSymbol) }.tag(1)
 
-                    Spacer()
+//                    Spacer()
 
                     NavigationStack { Adjustments.RootView(resolver: resolver) }
                         .tabItem {
@@ -1060,23 +1060,29 @@ extension Home {
                 }
                 .tint(Color.tabBar)
 
-                Button(
-                    action: {
-                        state.showModal(for: .treatmentView) },
-                    label: {
-                        Image(systemName: "plus.circle.fill")
-                            .font(.system(size: 40))
-                            .foregroundStyle(Color.tabBar)
-                            .padding(.vertical, 2)
-                            .padding(.horizontal, 24)
-                    }
-                )
-            }.ignoresSafeArea(.keyboard, edges: .bottom).blur(radius: state.waitForSuggestion ? 8 : 0)
-                .onChange(of: selectedTab) {
-                    if !settingsPath.isEmpty {
-                        settingsPath = NavigationPath()
-                    }
-                }
+//                Button(
+//                    action: {
+//                        state.showModal(for: .treatmentView) },
+//                    label: {
+//                        Image(systemName: "plus.circle.fill")
+//                            .font(.system(size: 40))
+//                            .foregroundStyle(Color.tabBar)
+//                            .padding(.vertical, 2)
+//                            .padding(.horizontal, 24)
+//                    }
+//                )
+//                Image(.trioCircledNoBackground)
+//                    .resizable()
+//                    .scaledToFit()
+//                    .frame(width: 42, height: 42)
+//                    .padding(.vertical, 2)
+//                    .shadow(color: Color.white.opacity(0.1), radius: 5, x: 0, y: 0)
+//            }.ignoresSafeArea(.keyboard, edges: .bottom).blur(radius: state.waitForSuggestion ? 8 : 0)
+//                .onChange(of: selectedTab) {
+//                    if !settingsPath.isEmpty {
+//                        settingsPath = NavigationPath()
+//                    }
+            }
         }
 
         var body: some View {

+ 13 - 9
Trio/Sources/Modules/Treatments/TreatmentsStateModel.swift

@@ -161,22 +161,26 @@ extension Treatments {
         }
 
         deinit {
-            // Unregister from broadcaster
-            if let broadcaster = broadcaster {
-                broadcaster.unregister(DeterminationObserver.self, observer: self)
-                broadcaster.unregister(BolusFailureObserver.self, observer: self)
-            }
+            debug(.bolusState, "StateModel deinit called")
+        }
 
-            // Cancel Combine subscriptions
-            unsubscribe()
+        private var hasCleanedUp = false
 
+        func cleanupTreatmentState() {
+            guard !hasCleanedUp else { return }
+            hasCleanedUp = true
+
+            unsubscribe()
             bolusProgressCancellable?.cancel()
 
-            debug(.bolusState, "Bolus.StateModel deinitialized")
+            broadcaster?.unregister(DeterminationObserver.self, observer: self)
+            broadcaster?.unregister(BolusFailureObserver.self, observer: self)
+
+            debug(.bolusState, "StateModel cleanup() finished")
         }
 
         private func setupBolusStateConcurrently() {
-            debug(.bolusState, "setupBolusStateConcurrently fired")
+            debug(.bolusState, "Setting up bolus state concurrently...")
             Task {
                 do {
                     try await withThrowingTaskGroup(of: Void.self) { group in

+ 3 - 0
Trio/Sources/Modules/Treatments/View/TreatmentsRootView.swift

@@ -388,6 +388,9 @@ extension Treatments {
             .onDisappear {
                 state.isActive = false
                 state.addButtonPressed = false
+
+                // Cancel all Combine subscriptions and unregister State from broadcaster
+                state.cleanupTreatmentState()
             }
             .sheet(isPresented: $state.showInfo) {
                 PopupView(state: state)