Почему переменная, обернутая в @State, не обновляется немедленно в SwiftUI

#swift #swiftui

#быстрый #свифтуи

Вопрос:

Согласно документации, изменение @State обернутой переменной обновит представление, которое ссылается на эту переменную. Но когда я пытался изменить @State обернутую переменную counter в цикле, я обнаружил, что она изменилась только после завершения цикла. Я также написал кое — какой код с DispatchQueue помощью . Используемый код DispatchQueue может обновлять counter немедленно (т. Е. Я могу видеть постоянно меняющееся значение в Text ).

Поэтому мне интересно, почему эти две части кода работают по-разному.

Вот мой код:

 import SwiftUI

struct ContentView: View {
    
    @State private var counter: Int = 0
    
    var body: some View {
        VStack {
            Text("Counter value: (counter)")
                .padding()
            Button("Begin Counting (Sync)", action: {() -> Void in
                for _ in 0..<100000 {
                    counter  = 1
                }
            })
            Button("Begin Counting (Async)", action: {() -> Void in
                DispatchQueue.global(qos: .userInitiated).async {
                    for _ in 0..<100000 {
                        counter  = 1
                    }
                }
            })
        }.frame(width: 200, height: 200, alignment: .center)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

 

Ответ №1:

Потому что вы должны обновить пользовательский интерфейс только в основной очереди. Это включает в себя обновление переменных @State. Это будет работать:

             DispatchQueue.global(qos: .userInitiated).async {
                for _ in 0..<100000 {
                    DispatchQueue.main.async { counter  = 1 }
                }
            }
 

Ответ №2:

Если цель состоит в том, чтобы увеличить счетчик 1 до 1000, удалите оператор for и отредактируйте действие счетчика:

counter = counter < 1000 ? 1 : 0