【问题标题】:Do I need DispatchQueue.main to update UI after an Alamofire request?在 Alamofire 请求后,我是否需要 DispatchQueue.main 来更新 UI?
【发布时间】:2016-12-14 05:55:00
【问题描述】:

我正在关注有关使用 REST/web requests 的教程。在本教程中,我们正在开发一个 Pokedex 应用程序,在该应用程序中,我们使用 Alamofire 从 API 获取 Pokemon 详细信息,然后在我们的 UI 中显示该数据。

相关代码如下:

typealias DownloadComplete = (Bool) -> ()

// Model class
func downloadPokemonDetails(completed: @escaping DownloadComplete)
    {
        Alamofire.request(_pokemonURL).responseJSON { (response) in
            var success = true
            if let jsonData = response.result.value as? Dictionary<String, Any>
            {
                // parse the json here
                ...
            }
            else
            {
                success = false
            }
            completed(success)
        }
    }

// Controller class
override func viewDidLoad() {
        super.viewDidLoad()
        pokemon.downloadPokemonDetails(completed: { (success) in
            if success
            {
                self.updateUI()
            }
            else
            {
                print("FAILED: TO PARSE JSON DATA")
            }
        })
    }

func updateUI()
{
    attackLbl.text = pokemon.attack
    defenseLbl.text = pokemon.defense
    heightLbl.text = pokemon.height
    weightLbl.text = pokemon.weight
}

现在我的问题是:我们不应该使用DispatchQueue.main. 并像这样更新那里的用户界面吗?

pokemon.downloadPokemonDetails(completed: { (success) in
            if success
            {
                DispatchQueue.main.async {
                    self.updateUI()
                }
            }

本教程省略了它,我不确定此处是否需要 DispatchQueue 来更新 UI。我知道在后台线程中更新 UI 是不好的做法,所以如果有人可以阐明是否需要在这里使用 DispatchQueue 来获取主线程,我将非常感激。

【问题讨论】:

  • 你看过Alamofire Readme吗? – “默认情况下,响应处理程序在主调度队列上执行......”
  • @MartinR 感谢您的评论。我实际上没有,但这是否意味着在这种情况下更新 UI 时我不再需要 DispatchQueue.main 了?我还是新手。
  • 你不需要。您可以通过dispatch_get_current_queue() == dispatch_get_main_queue()查看它
  • 感谢@NeilGaliaskarov 的确认。我想使用您发布的 sn-p 进行验证,但 dispatch_get_current_queue() 已被弃用,我无法使用它自己查找。我似乎找不到那个替代品。
  • if Thread.isMainThread { print("Main Thread") }

标签: ios swift alamofire grand-central-dispatch


【解决方案1】:

如果不想阅读整个 cmets 部分,我将其发布在这里作为答案。 首先,阅读Alamofire docs,其中明确指出:“默认情况下,响应处理程序在主调度队列上执行。”

这意味着,您可以在响应块中调用任何与 UI 相关的代码。如果您仍然对依赖 3rd 方 lib doc 感到不舒服,您可以通过执行 swift3sn-p 来检查:

if Thread.isMainThread { 
   print("Main Thread") 
}

xcode 9

xcode 9 开始,有一个内置的 Main Thread Checker 从后台线程检测 AppKit、UIKit 和其他 API 的无效使用。当您使用 Xcode 调试器运行应用程序时,Main Thread Checker 会自动启用。

如果您的项目的任何部分包含来自后台线程的无效 UI 调用,您将看到以下内容:

** 在 Xcode 版本 9.1 (9B55) 中演示

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 2017-11-15
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    相关资源
    最近更新 更多