Ios Swift-如何正确地从REST API获取数据到ViewController中的标签
我正在尝试创建一个iOS应用程序,以从API获取数据,并将其显示在标签中 到目前为止,我有: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
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) }