斯威夫特3 - 活动指示灯延迟或不响应
我时填写的字段内容,然后点击按钮域和按钮:斯威夫特3 - 活动指示灯延迟或不响应
@IBAction func dpSomething(_ sender: UIButton) {
activityIndicator.startAnimating()
activityIndicator.isHidden = false
field.isHidden = true
send.isHidden = true
let url = "http://urlwithjson"
let session = URLSession.shared
DispatchQueue.main.async { [unowned self] in
let task = session.dataTask(with: URL(string: url)!) { (data, response, error) in
if(error==nil){
do {
let jsonData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
if((jsonData["response"] as! Int) == 0){
self.responseL.text = "no results"
}
self.activityIndicator.stopAnimating()
self.responseL.isHidden = false
} catch _ {}
}
}
task.resume()
}
}
当我使用打印它打印我几乎立即的JSON,但活动指标需要10-20秒才能消失或有时不会消失。有人可以告诉我为什么吗?并且当我更改标签中的文本时,我在控制台中收到错误:
此应用程序正在从后台线程修改自动布局引擎,这可能导致引擎损坏和奇怪的崩溃。这将在未来的版本中引发异常。
为什么会发生这种情况?
首先添加以下代码activityIndicator.startAnimating()
后,该代码会隐藏活动指示灯那些你叫self.activityIndicator.stopAnimating()
:
activityIndicator.hidesWhenStopped = true
你也只能躲在活动指示灯如果响应成功,所以你可能需要在catch块中有错误时隐藏指示器,而在你从api响应中得到错误时可能需要隐藏指示器
另一点是当你提出你的请求时它不应该是主要的d,只是在后台,然后当你需要更新UI,那么请使用主线程,所以终于在这里是完整的代码,你可能需要:
@IBAction func dpSomething(_ sender: UIButton) {
activityIndicator.startAnimating()
activityIndicator.isHidden = false
activityIndicator.hidesWhenStopped = true
field.isHidden = true
send.isHidden = true
let url = "http://urlwithjson"
let session = URLSession.shared
let task = session.dataTask(with: URL(string: url)!) { (data, response, error) in
if(error==nil){
do {
let jsonData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
if((jsonData["response"] as! Int) == 0){
DispatchQueue.main.async {
//Update your UI here
self.responseL.text = "no results"
}
}
DispatchQueue.main.async {
//Update your UI here
self.activityIndicator.stopAnimating()
self.responseL.isHidden = false
}
} catch _ {
// JSONSerialization error might happen so hide the indicator
DispatchQueue.main.async {
//Update your UI here
self.activityIndicator.stopAnimating()
self.responseL.isHidden = false
}
}
}else {
// api response error might happen so hide the indicator
DispatchQueue.main.async {
//Update your UI here
self.activityIndicator.stopAnimating()
self.responseL.isHidden = false
}
}
}
task.resume()
}
现在它马上工作,但响应标签在10秒后发生变化:D,并且我仍然收到:此应用程序正在从主t访问引擎后从后台线程修改自动布局引擎hread。这可能会导致引擎损坏和奇怪的崩溃。 –
@BogdanBogdanov我编辑了我的答案,标签也必须从主线更新!让我知道它是否工作 – AaoIi
好现在它的工作感谢...:D –
您只需要在main
上修改UI
线程永远不会在主线程上调用异步API调用。
let task = session.dataTask(with: URL(string: url)!) { (data, response, error) in
if(error==nil){
do {
let jsonData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
if((jsonData["response"] as! Int) == 0){
self.responseL.text = "no results"
}
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
self.activityIndicator.isHidden = true
self.responseL.isHidden = false
}
} catch _ {}
}
}
task.resume()
伟大的工作@Nirav d –
@Ashok感谢队友:) –
看来这是不鼓励 –
在主线程上正在运行的网络请求而是试图'DispatchQueue.main.async { self.activityIndicator.stopAnimating() self.responseL.isHidden =假 }' –