【问题标题】:What is the correct way to retrieve all data and then filter into table view?检索所有数据然后过滤到表视图中的正确方法是什么?
【发布时间】:2019-07-23 05:18:16
【问题描述】:

我正在成功检索 Firebase 数据并将其加载到我的 tableview 中。在初始加载时,我根据日期查询数据,因此它只加载日期在当前日期之后的数据。我还有一个“过去”按钮,它以相同的方式查询数据,但只显示日期早于当前日期的数据。它可以工作,但是我在每次单击按钮时都会检索数据,并且它似乎会降低性能并且有时会崩溃。这是这样做的方法吗?或者我可以通过什么方式加载所有数据和带有按钮的查询/过滤器?

override func viewDidLoad() {
    super.viewDidLoad()
//Retrieving data from Firebase
    refReleases = Database.database().reference().child("releases");
    _ = refReleases.queryOrdered(byChild: "date").queryStarting(atValue: currentDate).observe(.value, with: { (snapshot) in
        if snapshot.childrenCount>0{
            self.releasesData.removeAll()
          for releases in snapshot.children.allObjects as![DataSnapshot]{
                let releaseObject = releases.value as? [String: AnyObject]
                let releaseName = releaseObject?["releaseName"]
                let releaseType = releaseObject?["releaseType"]
                let releasePrice = releaseObject?["releasePrice"]
                let releaseDate = releaseObject?["releaseDate"]
                let releaseImage = releaseObject?["releaseImage"]
                let releasetag = releaseObject?["releasetag"]
                let releaseStyleCode = releaseObject?["releaseStyleCode"]
                let release = ReleaseModel(releasetype: releaseType as! String?, releasename: releaseName as! String?, releaseprice: releasePrice as! String?, releasedate: releaseDate as! String?, releaseimage: releaseImage as! String?, releasetag: releasetag as! String?, releasestylecode: releaseStyleCode as! String?) 
                self.releasesData.insert(release, at: 0)
            }
            self.releasesData.reverse()
            self.tableView.reloadData()
        }

    }
    )}
}

//"Past" button
@IBAction func past(_ sender: UIButton) {
    refReleases = Database.database().reference().child("releases");
    _ = refReleases.queryOrdered(byChild: "date").queryEnding(atValue: currentDate).observe(.value, with: { (snapshot) in
        if snapshot.childrenCount>0{
            self.releasesData.removeAll()
            for releases in snapshot.children.allObjects as![DataSnapshot]{
                let releaseObject = releases.value as? [String: AnyObject]
                let releaseName = releaseObject?["releaseName"]
                let releaseType = releaseObject?["releaseType"]
                let releasePrice = releaseObject?["releasePrice"]
                let releaseDate = releaseObject?["releaseDate"]
                let releaseImage = releaseObject?["releaseImage"]
                let releasetag = releaseObject?["releasetag"]
                let releaseStyleCode = releaseObject?["releaseStyleCode"]
                let release = ReleaseModel(releasetype: releaseType as! String?, releasename: releaseName as! String?, releaseprice: releasePrice as! String?, releasedate: releaseDate as! String?, releaseimage: releaseImage as! String?, releasetag: releasetag as! String?, releasestylecode: releaseStyleCode as! String?)
                self.releasesData.insert(release, at: 0)
            }
            self.tableView.reloadData()
        }

    }
    )}

【问题讨论】:

  • 正确的方法是一次获取数据并在本地过滤。
  • @TheTiger 如何在本地过滤?
  • 你能分享你的崩溃信息吗?

标签: swift xcode firebase firebase-realtime-database


【解决方案1】:

您基本上每次单击“过去”按钮时都会添加观察者。 每次数据库中的值更改时,observe 方法都会触发。 另外,删除handleviewDidDisappear

如果要手动读取一次数据,请使用observeSingleEvent 方法。 它只会触发一次。

另外,看看这个firebase blog post。 它显示了监听器的放置位置。

var handle: DatabaseHandle!

override func viewDidLoad() {
    super.viewDidLoad()
    //  Retrieving data from Firebase
    refReleases = Database.database().reference().child("releases")
}

override func viewWillApear(_ animated: Bool) {
    super.viewWillAppear(animated)
    handle = refReleases
        .queryOrdered(byChild: "date")
        .queryStarting(atValue: currentDate)
        .observe(.value) { snapshot in
            if snapshot.childrenCount > 0 {
                self.releasesData.removeAll()

                for releases in snapshot.children.allObjects as! [DataSnapshot] {
                    let releaseObject = releases.value as? [String: AnyObject]
                    let releaseName = releaseObject?["releaseName"]
                    let releaseType = releaseObject?["releaseType"]
                    let releasePrice = releaseObject?["releasePrice"]
                    let releaseDate = releaseObject?["releaseDate"]
                    let releaseImage = releaseObject?["releaseImage"]
                    let releasetag = releaseObject?["releasetag"]
                    let releaseStyleCode = releaseObject?["releaseStyleCode"]

                    let release = ReleaseModel(
                        releasetype: releaseType as! String?,
                        releasename: releaseName as! String?,
                        releaseprice: releasePrice as! String?,
                        releasedate: releaseDate as! String?,
                        releaseimage: releaseImage as! String?,
                        releasetag: releasetag as! String?,
                        releasestylecode: releaseStyleCode as! String?) 
                    self.releasesData.insert(release, at: 0)
                }
                self.releasesData.reverse()
                self.tableView.reloadData()
            }
        }
    }
}

override func viewDidDisappear(_ animated: Bool) {
    if let handle = handle {
        refReleases.removeObserver(withHandle: handle)
    }
}

【讨论】:

    【解决方案2】:

    但是我每次点击按钮时都会检索数据,而且速度似乎变慢了 性能有时会崩溃

    因为你阻塞了主线程,你可以在Dispatch.main.async {}中做到这一点

    【讨论】:

    • @CARGI 我在Dispatch.main.async {} 中做什么?
    【解决方案3】:

    李杰是对的。您不应该每次点击都添加观察者。您可以在过去的按钮中执行此操作,单击检查您的查询。如果存在,请将其删除。

            private var queryPast: Query?; // be sure firebase query. I do not remember. 
             override func viewDidLoad() 
            {
                    super.viewDidLoad()
                //Retrieving data from Firebase
                    refReleases = Database.database().reference().child("releases");
                    _= refReleases.queryOrdered(byChild: "date").queryStarting(atValue: currentDate).observe(.value, with: { (snapshot) in
                        if snapshot.childrenCount>0{
                            self.releasesData.removeAll()
                          for releases in snapshot.children.allObjects as![DataSnapshot]{
                                let releaseObject = releases.value as? [String: AnyObject]
                                let releaseName = releaseObject?["releaseName"]
                                let releaseType = releaseObject?["releaseType"]
                                let releasePrice = releaseObject?["releasePrice"]
                                let releaseDate = releaseObject?["releaseDate"]
                                let releaseImage = releaseObject?["releaseImage"]
                                let releasetag = releaseObject?["releasetag"]
                                let releaseStyleCode = releaseObject?["releaseStyleCode"]
                                let release = ReleaseModel(releasetype: releaseType as! String?, releasename: releaseName as! String?, releaseprice: releasePrice as! String?, releasedate: releaseDate as! String?, releaseimage: releaseImage as! String?, releasetag: releasetag as! String?, releasestylecode: releaseStyleCode as! String?) 
                                self.releasesData.insert(release, at: 0)
                            }
                            self.releasesData.reverse()
                            self.tableView.reloadData()
                        }
    
                    }
                    )}
                }
    
                //"Past" button
                @IBAction func past(_ sender: UIButton) {
              if (self.queryPast != nil)
              {
                 self.queryPast.removeObserver();
                  // I DO NOT REMEMBER currently syntax. but you have  do something 
      like that.
              }
                    refReleases = Database.database().reference().child("releases");
                    self.queryPast = refReleases.queryOrdered(byChild: "date").queryEnding(atValue: currentDate);
           self.queryPast.observe(.value, with: { (snapshot) in
                        if snapshot.childrenCount>0{
                            self.releasesData.removeAll()
                            for releases in snapshot.children.allObjects as![DataSnapshot]{
                                let releaseObject = releases.value as? [String: AnyObject]
                                let releaseName = releaseObject?["releaseName"]
                                let releaseType = releaseObject?["releaseType"]
                                let releasePrice = releaseObject?["releasePrice"]
                                let releaseDate = releaseObject?["releaseDate"]
                                let releaseImage = releaseObject?["releaseImage"]
                                let releasetag = releaseObject?["releasetag"]
                                let releaseStyleCode = releaseObject?["releaseStyleCode"]
                                let release = ReleaseModel(releasetype: releaseType as! String?, releasename: releaseName as! String?, releaseprice: releasePrice as! String?, releasedate: releaseDate as! String?, releaseimage: releaseImage as! String?, releasetag: releasetag as! String?, releasestylecode: releaseStyleCode as! String?)
                                self.releasesData.insert(release, at: 0)
                            }
                            self.tableView.reloadData()
                        }
    
                    }
                    )}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多