Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift-如何正确地从REST API获取数据到ViewController中的标签_Ios_Swift - Fatal编程技术网

Ios Swift-如何正确地从REST API获取数据到ViewController中的标签

Ios Swift-如何正确地从REST API获取数据到ViewController中的标签,ios,swift,Ios,Swift,我正在尝试创建一个iOS应用程序,以从API获取数据,并将其显示在标签中 到目前为止,我有: func getJoke(completion: @escaping (ChuckNorrisResponse) -> ()) { URLSession.shared.dataTask(with: URL(string: url)!) { data, response, error in guard let data = data, error == nil

我正在尝试创建一个iOS应用程序,以从API获取数据,并将其显示在标签中

到目前为止,我有:

func getJoke(completion: @escaping (ChuckNorrisResponse) -> ()) {
        URLSession.shared.dataTask(with: URL(string: url)!) { data, response, error in
            guard let data = data, error == nil else {
                print("Something fucked up")
                return
            }
            
            var result: ChuckNorrisResponse?
            do {
                result = try JSONDecoder().decode(ChuckNorrisResponse.self, from: data)
            } catch {
                print("Fucked up to convert \(error.localizedDescription)")
            }
            
            guard let joke = result else {
                return
            }
            
            completion(joke)
        }.resume()
    }
和在ViewController中

func setNewJoke() {
        jokesProvier.getJoke { joke in
            self.JokeLabel.text = joke.value
        }
但我不喜欢在闭包内编辑标签中的文本。 它显示错误-UILabel。文本只能从主线程使用

我找不到任何地方,我应该如何正确地这样做,使它的工作


提前感谢

我建议调用主线程上的完成处理程序。所以不是

completion(joke)


基本上,正如Aaron所说,您必须使用
DispatchQueue.main.async
将闭包传递给主线程。原因是
URLSession.shared.dataTask
completionHandler在不同于main的线程上运行,并且
self.JokeLabel.text=joke.value
是一个UI更新-您正在更改标签上的文本,UIKit要求您更新主线程上的屏幕!这就是为什么必须将标签更新传递给主线程。尝试在与main不同的线程上更新它将导致未定义的行为-它可能会工作,可能会冻结,可能会崩溃。
因此,每当您在后台线程上执行某项操作,并且在某个时刻想要更新UI时,请始终将此作业传递给主线程
希望这对您有所帮助。
DispatchQueue.main.async{self.JokeLabel.text=joke.value}
非常感谢您澄清它的工作原理。
DispatchQueue.main.async { completion(joke) }