Публикация SwiftUI из фонового процесса в главное представление

Я пытаюсь перенести данные из цикла фонового выполнения в главное представление. Мой фрагмент кода приведен ниже.

Я вижу, что счетчик будет увеличиваться (печать в терминале), но представление не обновляет текущее значение. Отображаемое значение по-прежнему равно нулю каждый раз.

Все знали? Большое спасибо!

import SwiftUI

struct ContentView: View {
    
    @EnvironmentObject var loop : Loop
    
    var body: some View {
        
        VStack {
            Text("Content View")
            LoopView()
        }
    }
}

struct LoopView: View {
    
    @EnvironmentObject var loop : Loop
    
    var body: some View {
        
        VStack {
            
            Text("Loop View")
            
            HStack {
                Text("i = ")
                Text("\(loop.i)")
            }
        }
    }
}


class Loop : ObservableObject {
    
    @Published var i : Int
    
    func startLoop() {
        
        while true {
            print("i = \(self.i)")
            self.i += 1
            
            sleep(1)
        }

    }
    
    init() {
          
        DispatchQueue.main.async {
            self.startLoop()
        }
        
    }
}


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

1 ответ

Решение

Это потому что ваш sleep фактически работает в основном потоке (DispatchQueue.main). Если вы действительно хотите использоватьsleep запустить его в фоновом режиме DispatchQueue.global(). Но тогда вам нужно использоватьDispatchQueue.main снова, чтобы обновить @Published переменная:

class Loop: ObservableObject {
    @Published var i: Int

    func startLoop() {
        while true {
            print("i = \(self.i)")
            DispatchQueue.main.async {
                self.i += 1
            }

            sleep(1)
        }
    }

    init() {
        DispatchQueue.global(qos: .background).async {
            self.startLoop()
        }
    }
}

В качестве альтернативы вы можете посмотреть на повторяющиеся таймеры, которые сделают всю работу за вас:

Другие вопросы по тегам