2017-06-05 46 views
1

我在TableView中顯示JSON數據,但應用程序很慢。顯示前5-10秒鐘等待。 我在Xcode輸出收到這個錯誤:JSON數據到表視圖太慢

2017年6月5日12:49:47.505 Ekstraders [1167:137558]本申請是 從後臺線程修改自動佈局引擎 發動機被訪問後來自主線程。這可能會導致引擎 損壞和奇怪的崩潰。


Stack:(
    0 CoreFoundation      0x000000010ad78b0b __exceptionPreprocess + 171 
    1 libobjc.A.dylib      0x0000000108020141 objc_exception_throw + 48 
    2 CoreFoundation      0x000000010ade1625 +[NSException raise:format:] + 197 
    3 Foundation       0x0000000107d1917b _AssertAutolayoutOnAllowedThreadsOnly + 105 
    4 Foundation       0x0000000107d18f0f -[NSISEngine _optimizeWithoutRebuilding] + 61 
    5 Foundation       0x0000000107b487e6 -[NSISEngine optimize] + 108 
    6 Foundation       0x0000000107d16ef4 -[NSISEngine performPendingChangeNotifications] + 84 
    7 UIKit        0x00000001085b5412 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1787 
    8 QuartzCore       0x000000010dce6904 -[CALayer layoutSublayers] + 146 
    9 QuartzCore       0x000000010dcda526 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 370 
    10 QuartzCore       0x000000010dcda3a0 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24 
    11 QuartzCore       0x000000010dc69e92 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294 
    12 QuartzCore       0x000000010dc96130 _ZN2CA11Transaction6commitEv + 468 
    13 QuartzCore       0x000000010dc9642c _ZN2CA11Transaction14release_threadEPv + 214 
    14 libsystem_pthread.dylib    0x000000010c065413 _pthread_tsd_cleanup + 544 
    15 libsystem_pthread.dylib    0x000000010c06514d _pthread_exit + 152 
    16 libsystem_pthread.dylib    0x000000010c0636d1 pthread_attr_getschedpolicy + 0 
    17 libsystem_pthread.dylib    0x000000010c0630f1 start_wqthread + 13 
) 

ViewController.swift:

import UIKit 


class FirstViewController: UIViewController,UITableViewDataSource,UITableViewDelegate { 

    @IBOutlet weak var tableView: UITableView! 

    var tbCount = 0 

    var myMp3s = [Mp3]() 


    override func viewDidLoad() { 
     super.viewDidLoad() 


     tableView.dataSource = self 
     tableView.delegate = self 


     let url = URL(string: "example.php") 

     DispatchQueue.main.async() { //JSON to Mp3 object. 


     URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in 
      guard let data = data, error == nil else { return } 


      do { 
       let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any] 
       let posts = json["server_response"] as? [[String: Any]] ?? [] 

       for i in posts { 

        print(i["id"]!) 

        let mp3 = Mp3(id: i["id"] as! String, category: i["kategori"] as! String) 

        self.myMp3s.append(mp3) 


       } 

       self.tableView.reloadData() 
       self.tableView.tableFooterView = UIView(frame: .zero) 

       print("counte", self.myMp3s.count) 


      } catch let error as NSError { 
       print(error) 
      } 
     }).resume() 

     } 

    } 



    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return myMp3s.count 

    } 
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 

     var height:CGFloat = CGFloat() 

     height = 100 
     return height 
    } 


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 



     let cell = UITableViewCell() 
     cell.backgroundColor = UIColor.darkGray 



     //Design 
     cell.textLabel?.text = self.myMp3s[indexPath.row].category 

     cell.textLabel?.backgroundColor = .red 
     cell.textLabel?.layer.borderWidth = 3 
     cell.textLabel?.layer.borderColor = UIColor.lightGray.cgColor 
     cell.textLabel?.heightAnchor.constraint(equalToConstant: 50).isActive = true 
     cell.textLabel?.widthAnchor.constraint(equalToConstant: 200).isActive = true 


     cell.textLabel?.layer.cornerRadius = 10 
     cell.textLabel?.clipsToBounds = true 
     cell.textLabel?.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true 
     cell.textLabel?.centerXAnchor.constraint(equalTo: cell.centerXAnchor).isActive = true 

     cell.textLabel?.textAlignment = .center 
     cell.textLabel?.textColor = .white 
     cell.textLabel?.font = UIFont.boldSystemFont(ofSize: 16.0) 

     return cell 


    } 


    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
     print(myMp3s[indexPath.row].category) 
    } 


    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

} 

我可以顯示的tableview JSON數據,沒有問題,但問題是,它是太慢了。它正在等待顯示。 我該如何解決這個問題?我錯在哪裏?

+3

上主線程執行用戶界面的變化'DispatchQueue.main.async {self.tableView.reloadData() self.tableView.tableFooterView = UIView的(幀:.zero)}' –

回答

2

URLSession.shared.dataTask正在後臺線程中執行完成處理程序。這會導致意想不到的問題,因爲影響UI的操作必須由主線程完成。

因此,你應該換那些部分與DispatchQueue.main.async {}

DispatchQueue.main.async { 
    self.tableView.reloadData() 
    self.tableView.tableFooterView = UIView(frame: .zero) 
} 
0

在主線程上更新您的UI。

URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in 

    guard let data = data, error == nil else { return } 

    DispatchQueue.main.async { 

     do { 
      let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any] 
      let posts = json["server_response"] as? [[String: Any]] ?? [] 

      for i in posts { 

       print(i["id"]!) 
       let mp3 = Mp3(id: i["id"] as! String, category: i["kategori"] as! String) 
       self.myMp3s.append(mp3) 
     } 

     self.tableView.reloadData() 
     self.tableView.tableFooterView = UIView(frame: .zero) 
     print("counte", self.myMp3s.count) 


     } catch let error as NSError { 
     print(error) 
     } 
    } 
}).resume() 
0
  1. 您收到的數據是大的,或者如果是小,你可能會遇到網絡problems.To檢查的數據量和平均時間,使用REST客戶端獲取數據。您可以使用PostmanARC來了解數據。
  2. 正如其他人提到的那樣,當您從後臺線程進行UI更改時,您會收到錯誤(不是崩潰),我相信。現在你所做的網絡調用是一個異步調用,這意味着它在後臺線程中被調用,一旦它啓動。您應該始終從主線程進行UI更改。

    DispatchQueue.main.async { 
        self.tableView.reloadData() 
        self.tableView.tableFooterView = UIView(frame: .zero) 
    }