Post

Replies

Boosts

Views

Activity

Reply to @StateObject and view installation
I cannot provide exact repro steps as the bug is intermittent. But I can provide some general code as to how the StateObjects are used: import SwiftUI import Combine struct RootView: View {   private let columns: [GridItem] = [     GridItem(.flexible()),     GridItem(.flexible())   ]   var body: some View {     ScrollView {       LazyVGrid(columns: columns) {         ForEach(0..<20) { _ in           ContentView()         }       }     }   } } struct ContentView: View {   @StateObject   private var viewModel = ViewModel()       var body: some View {     content(viewModel.viewState)       .onAppear {         viewModel.subscribe()       }   }       @ViewBuilder   private func content(_ viewState: ViewState) -> some View {     switch viewState {     case .loading:       ProgressView()     case .content(let counter):       Text("\(counter)")         .padding()     }   } } extension ContentView {         enum ViewState: ObservableViewState {     case loading     case content(Int)           static var initialViewState: ViewState = .loading   }       enum Input {     case timerUpdated   }       enum Action {     case increment     case setState(ViewState)   }       class ViewModel: ObservableObject {     @Published     var viewState: ViewState = .loading     private let inputSubject = PassthroughSubject<Input, Never>()     private var subscribed = false     var internalInputPublisher: AnyPublisher<Input, Never> {       Timer.publish(every: 1, on: RunLoop.main, in: .common)         .autoconnect()         .eraseToAnyPublisher()         .map({ _ in           Input.timerUpdated         })         .eraseToAnyPublisher()     }           func subscribe() {       if subscribed {         return       }       subscribed = true       Publishers.Merge(internalInputPublisher, inputSubject)         .flatMap { input -> AnyPublisher<Action, Never> in           switch input {           case .timerUpdated:             return Just(.increment)               .eraseToAnyPublisher()           }         }         .scan(viewState, { currentState, action in           switch action {           case .setState(let state):             return state           case .increment:             if case .content(let counter) = currentState {               return .content(counter + 1)             } else {               return .content(1)             }           }         })         .removeDuplicates()         .assign(to: &$viewState)     }           func send(_ input: Input) {       inputSubject.send(input)     }   } } pretty much all view models follow this reactive publisher pattern for channeling view state updates to the listening view. The bug can happen to random views throughout the app
Sep ’21