Утечка памяти SwiftUI с помощью форм и списков - PullRequest
3 голосов
/ 11 января 2020

Я занимаюсь разработкой простого приложения с SwiftUI. Во время моих тестов я заметил, что мои модели представлений никогда не вызывают deinit и вызывают линейное увеличение использования памяти.

Я воспроизвел такое же поведение со следующим кодом:

struct ContentView: View {
    @State private var isPresented = false

    var body: some View {
        Button("open") {
            self.isPresented = true
        }
        .sheet(isPresented: $isPresented) {
            SheetView()
        }
    }
}

struct SheetView: View {
    @ObservedObject var model: ViewModel

    init() {
        model = ViewModel()
    }

    var body: some View {
        Form {
            Toggle("Toggle Me", isOn: $model.isOn)
        }
    }
}

class ViewModel: ObservableObject {
    @Published var isOn = false

    deinit {
        print("ViewModel deinit ")
    }
}

Когда лист распускается, модельный объект никогда не деиницируется. Если я заменю форму с VStack или ScrollView, то модель не определена. Есть ли решение для этого?

Ответы [ 2 ]

0 голосов
/ 29 января 2020

Это ошибка. Единственный обходной путь, который мне помог, - это использование ScrollView. С другой стороны, ScrollView поставляется с собственными ошибками анимации.

EDIT

Кажется, проблема решена в iOS 13.3.1

0 голосов
/ 11 января 2020

Ты понимаешь deinit() неправильно. Когда вы отклоняете View, это не обязательно означает, что он будет звонить deinit(), как вы думаете. Однако если ваш ViewModel был уничтожен, он вызвал бы deinit(), как вы ожидаете.

Чтобы продемонстрировать это, вот класс Person со свойством name, простой инициализатор и метод printGreeting(), который печатает сообщение:

class Person {
    var name = "John Doe"

    init() {
        print("\(name) is alive!")
    }

    func printGreeting() {
        print("Hello, I'm \(name)")
    }
}

Мы собираемся создать несколько экземпляров класса Person внутри al oop, потому что каждый раз, когда l oop обходит, создается новый человек затем уничтожено:

for _ in 1...3 {
    let person = Person()
    person.printGreeting()
}

А теперь для деинициализатора. Это будет вызвано, когда экземпляр Person будет уничтожен :

deinit {
    print("\(name) is no more!")
}

Источник: https://www.hackingwithswift.com/sixty/8/6/deinitializers

...