swift - 如果委托已被使用,为什么我需要管理/更新主线程

我有一个异步 api 调用,我正在使用委托模式并分配了一个协议方法来处理当我们收到来自 api 的响应时如何处理数据

didWeatherUpdate

我在委托中实现了这一点。我理解它的方式,在异步网络请求完成之前,我用来使用来自 api 的数据更新 UI 的这种方法不会触发。

我的问题是为什么需要明确告诉主线程它是一个异步进程。如果在api调用完成后数据准备好之前不会调用该函数。我的假设是,当数据准备好时,函数会触发,然后添加到主线程工作的队列中。从完整的堆栈背景来看,这似乎是额外的

func didWeatherUpdate(_ weatherManager: WeatherManager,_ weather: WeatherModel){
        print("\(weather.temperature) from the controller")
        DispatchQueue.main.async{
            self.temperatureLabel.text = weather.temperatureString
        }

回答1

这是你的功能

func didWeatherUpdate(_ weatherManager: WeatherManager,_ weather: WeatherModel){
    print("\(weather.temperature) from the controller")
    DispatchQueue.main.async{
        self.temperatureLabel.text = weather.temperatureString
    }
}

此函数在后台线程上调用。 print 行在该线程上完成。

如果您尝试将 self.temperatureLabel.text = weather.temperatureString 作为下一行而不将其包装在 DispatchQueue 异步块中,那么它将立即在后台运行并导致运行时警告,因为您不允许在后台更新 UI。

要更新 UI,您需要将您的行包装在一个块中并将其发送到主队列而不是等待它。这正是它的作用

DispatchQueue.main.async {
    self.temperatureLabel.text = weather.temperatureString
}

这里的 async 没有告诉主队列数据获取是异步的。意思是您希望将块异步发送到主队列,而不是让后台线程等待 UI 更新。如果你在这之后有一个 print 行,它可能发生在 UI 更新之前。

如果您希望后台线程等待 UI,您将使用 DispatchQueue.main.sync

相似文章

随机推荐

最新文章