У меня проблемы с управлением памятью в SwiftUI и Combine.
Например, если у меня есть NavigationView, а затем перейдите к подробному представлению с помощью TextField, введите значение в TextField и коснитесь на кнопке "Назад", в следующий раз, когда я go перейду к этому представлению, TextField будет иметь ранее введенное значение.
Я заметил, что модель представления все еще находится в памяти после того, как подробное представление отклонено, и, вероятно, поэтому TextField по-прежнему содержит значение.
В UIKit при отклонении ViewController модель представления будет освобождена, а затем создана снова, когда ViewController будет представлен. Кажется, здесь это не так.
Я прилагаю минимальный воспроизводимый код для этой проблемы.
import SwiftUI
import Combine
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: OtherView()) {
Text("Press Here")
}
}
}
}
struct OtherView: View {
@ObservedObject var viewModel = ViewModel()
var body: some View {
VStack {
TextField("Something", text: $viewModel.enteredText)
.textFieldStyle(RoundedBorderTextFieldStyle())
Button(action: {
print("Tap")
}) {
Text("Tapping")
}.disabled(!viewModel.isValid)
}
}
}
class ViewModel: ObservableObject {
@Published var enteredText = ""
var isValid = false
var cancellable: AnyCancellable?
init() {
cancellable = textValidatedPublisher.receive(on: RunLoop.main)
.assign(to: \.isValid, on: self)
}
deinit {
cancellable?.cancel()
}
var textValidatedPublisher: AnyPublisher<Bool, Never> {
$enteredText.map {
$0.count > 1
}.eraseToAnyPublisher()
}
}
Я также заметил, что если, например, я добавляю другое представление, скажем, SomeOtherView после OtherView, затем каждый раз, когда я ввожу TextField из OtherView, вызывается деинициализация из модели просмотра SomeOtherView. Может ли кто-нибудь объяснить, почему это происходит?