【问题标题】:Access Firebase variable outside Closure在闭包之外访问 Firebase 变量
【发布时间】:2017-10-05 01:10:29
【问题描述】:

我正在尝试使用 Firebase 设置我的 CollectionView 中的单元格数量。我尝试创建一个局部变量并将其设置为与 Firebase 变量相同的值,但是当我尝试在函数外部使用它时它不起作用。我也尝试在 ViewWillAppear 中进行设置,但没有成功。

我设置导航栏标题来查看值。当它设置在闭包中时,我得到了正确的值,当我在闭包之外(在 firebase 函数之后)编写它时,它给出的值为 0。

我正在使用 swift 3

override func viewWillAppear(_ animated: Bool) {

        FIRDatabase.database().reference(withPath: "data").child("numCells").observeSingleEvent(of: .value, with: { (snapshot) in

            if let snapInt = snapshot.value as? Int {


               // self.navigationItem.title = String(snapInt)
                self.numCells = snapInt


            }

        }) { (error) in
            print(error.localizedDescription)
        }

        self.navigationItem.title = String(numCells)

    }

...

 override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of items


       return numCells

    }

【问题讨论】:

  • 在更新numCells 后,您是否在做self.collectionView.reloadData()
  • 当我在闭包外将标签设置为 numCells 时,它给出了 0 值,所以我认为问题就在那里。我刚刚尝试过,现在它工作得很好!谢谢,您可以将其发布为答案。 @Downgoat
  • 这只是有时会起作用!
  • 更具体的解决方案是什么? @Jay

标签: swift firebase firebase-realtime-database uicollectionview uicollectionviewcell


【解决方案1】:

Firebase 是异步的,数据只有在闭包内从 Firebase 返回时才有效。

 FIRDatabase.database().reference(withPath: "data").child("numCells")
                      .observeSingleEvent(of: .value, with: { snapshot in
      if let snapInt = snapshot.value as? Int {
           self.navigationItem.title = String(snapInt)
      }
 })

由此展开,假设我们要填充一个数组以用作 tableView 的数据源。

class ViewController: UIViewController {
    //defined tableView or collection or some type of list
    var usersArray = [String]()
    var ref: FIRDatabaseReference!

     func loadUsers() {
          let ref = FIRDatabase.database().reference()
          let usersRef = ref.child("users")

          usersRef.observeSingleEvent(of: .value, with: { snapshot in
              for child in snapshot {
                  let userDict = child as! [String: AnyObject]
                  let name = userDict["name"] as! string
                  self.usersArray.append[name]
              }
              self.myTableView.reloadData()
          })
     }
     print("This will print BEFORE the tableView is populated")
}

请注意,我们从闭包中填充数组,它是一个类 var,一旦填充了该数组,仍然在闭包中,我们刷新 tableView。

请注意,打印功能将在填充 tableView 之前发生,因为该代码是同步运行的,并且代码比互联网更快,因此关闭实际上会在打印语句之后发生。

【讨论】:

  • 如果您希望在打印语句之前完成更接近的操作,该怎么做?
  • @Mokadillion 将打印语句放在代码之后在闭包中。 Firebase 数据已准备好在闭包中使用(有效),因此您需要围绕确保数据可用的 UI 进行规划,然后再开始使用它。
猜你喜欢
  • 1970-01-01
  • 2021-05-28
  • 1970-01-01
  • 2017-06-25
  • 2014-11-11
  • 2013-04-24
  • 2017-05-24
  • 1970-01-01
  • 2012-08-31
相关资源
最近更新 更多