后台模式下iOS应用程序中的DispatchQueue.main?

3
如果URLSession发送请求并在获取响应之前iOS应用程序进入后台模式,会发生什么?self.myLabel.text会更新吗?DispatchQueue.main会起作用吗?
func updateUILabel(callback :(NSDictionary?) -> Void ){


    // create post request
    let url = URL(string: "https:anyserver.xyz”)!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        DispatchQueue.main.async({
              guard let data = data, error == nil else {
                print(error?.localizedDescription ?? "No data")
              }

              let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
              if let responseJSON = responseJSON as? [String: Any] {
                 self.myLabel.text = responseJSON[“text”] as! String
              }
       })
    }

    task.resume()
}
2个回答

2

您可以像这样做:

func updateUILabel(callback :(NSDictionary?) -> Void ){


    // create post request
    let url = URL(string: "https:anyserver.xyz”)!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        DispatchQueue.main.async({
              guard let data = data, error == nil else {
                print(error?.localizedDescription ?? "No data")
              }

              let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
              if let responseJSON = responseJSON as? [String: Any] {
                //Update
                 DispatchQueue.main.async {

                       self.myLabel.text = responseJSON[“text”] as! String                         

                 }

              }
       })
    }

    task.resume()
}

我刚刚更新了这个内容,

//Update
                 DispatchQueue.main.async {

                       self.myLabel.text = responseJSON[“text”] as! String                         

                 }

如果在调用URLSession后应用程序快速进入后台模式,'DispatchQueue.main.async'是否有效?同时,如果应用程序处于后台模式,主线程的行为是什么? - sulabh qg
1
是的,我曾经为我的代码做过一次,但作为最佳实践,当应用程序进入后台时,我们不应更新任何UI,而是可以在应用程序处于后台时收集这些数据,当应用程序回到前台时,我们可以更新我们的UI。此外,您可以在应用程序处于后台时将响应字符串保存在NSUserDefault中,当应用程序回到前台时,您可以从该userdefault更新标签。这里有一个教程可能会有所帮助,https://www.raywenderlich.com/143128/background-modes-tutorial-getting-started - Hitesh Sultaniya

1
在这种情况下,最佳实践是必须使用weak self而不是strong self来避免内存泄漏或安全访问。并且仅使用DispatchQueue.main.async来更新UI的代码 :)
func updateUILabel(callback :(NSDictionary?) -> Void ){


    // create post request
    let url = URL(string: "https:anyserver.xyz”)!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"

    let task = URLSession.shared.dataTask(with: request) {[weak self] data, response, error in
           guard let data = data, error == nil else {
              print(error?.localizedDescription ?? "No data")
              return
           }
           let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
              if let responseJSON = responseJSON as? [String: Any] {
                //Update
                 DispatchQueue.main.async {

                       self?.myLabel?.text = responseJSON[“text”] as? String                         

                 }

              }
       })
    }

    task.resume()
}

我在你的闭包前添加了[weak self]并更新了self?.myLabel?.text =...

根据苹果文档,您不应该从后台模式更新任何视图。

"避免更新您的窗口和视图。因为当您的应用程序处于后台时,您的应用程序的窗口和视图是不可见的,所以您应该避免更新它们。例外情况是在需要在拍摄应用程序快照之前更新窗口内容的情况下。" 链接:https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html


是的,你说得对,我没有加上[weak self]。但是标签如何从后台更新呢?请给我任何链接。 - sulabh qg
@sulabhqg 抱歉,我已经更新了我的答案,遵循苹果文档,你不应该在后台模式下更新任何视图。避免更新您的窗口和视图。因为当您的应用程序处于后台时,您的应用程序的窗口和视图是不可见的,所以您应该避免更新它们。唯一的例外是在需要在拍摄应用快照之前更新窗口内容的情况下。链接: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html - Sua Le

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接