斯威夫特3 - 活动指示灯延迟或不响应

斯威夫特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秒才能消失或有时不会消失。有人可以告诉我为什么吗?并且当我更改标签中的文本时,我在控制台中收到错误:

此应用程序正在从后台线程修改自动布局引擎,这可能导致引擎损坏和奇怪的崩溃。这将在未来的版本中引发异常。

为什么会发生这种情况?

+0

看来这是不鼓励 –

+0

在主线程上正在运行的网络请求而是试图'DispatchQueue.main.async { self.activityIndi​​cator.stopAnimating() self.responseL.isHidden =假 }' –

首先添加以下代码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() 

} 
+0

现在它马上工作,但响应标签在10秒后发生变化:D,并且我仍然收到:此应用程序正在从主t访问引擎后从后台线程修改自动布局引擎hread。这可能会导致引擎损坏和奇怪的崩溃。 –

+1

@BogdanBogdanov我编辑了我的答案,标签也必须从主线更新!让我知道它是否工作 – AaoIi

+1

好现在它的工作感谢...: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() 
+1

伟大的工作@Nirav d –

+0

@Ashok感谢队友:) –