2017-06-05 5 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. 
    } 

} 

私は、テーブルビューでは問題をJSONデータを表示することはできませんが、問題は、それは遅すぎるということです。表示する前に待っています。 この問題を解決するにはどうすればよいですか?どこが間違っていますか?

+3

メインスレッドで 'DispatchQueue.main.async UIの変更を実行{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クライアントを使用してそのデータをフェッチします。 PostmanまたはARCを使用してデータを知ることができます。
  2. 誰もが言及したように、あなたはバックグラウンドスレッドからUIの変更を行っているので、あなたはそのエラーを受けています(クラッシュしません)。これで、作成しているネットワークコールは非同期呼び出しとなります。つまり、開始されるとバックグラウンドスレッドで呼び出されます。メインスレッドから常にUIの変更を行う必要があります。

    DispatchQueue.main.async { 
        self.tableView.reloadData() 
        self.tableView.tableFooterView = UIView(frame: .zero) 
    } 
    
関連する問題