2

I have such example ViewModel and what I can see in Instruments is that such and similar ViewModel is leaking memory

class SearchViewModel<T>: ObservableObject {

    @Published var searchTerm : String = ""
    @Published var results: [T] = []

    private var disposables = Set<AnyCancellable>()

    init() {

        _searchTerm.projectedValue
        //$searchTerm
            .debounce(for: .milliseconds(350), scheduler: DispatchQueue.global())
            .flatMap { [weak self] term -> AnyPublisher<[T], Never> in

                 self?.search(by: term) ?? Empty().eraseToAnyPublisher()
            }
            .print("searching")
            .receive(on: DispatchQueue.main)
            .assignNotRetain(to: \.results, on: self)
            //.assign(to: \.results, on: self)
            .store(in: &disposables)

    }

    open func search(by term: String) -> AnyPublisher<[T], Never> {
        fatalError()
    }
}

I've added [weak self] in flatMap and .assign(to) changed to custom .assignNotRetain(to) which uses sink with [weak self] it leaks less (there are deinit calls) but there is more init calls then deinit calls! This causes disposables: Set to be not deallocated/cancelled subscriptions

It just example view model similar approach with calling serivce and then observing output via sink, assign and updating @Published all happens to leak memory and disposables usually are not deallocated so, should I cancell AnyCancellable manually in View onDisappear?

Michał Ziobro
  • 10,759
  • 11
  • 88
  • 143

0 Answers0