访问闭包Swift3之外的变量

时间:2017-04-21 00:47:34

标签: ios firebase swift3 firebase-realtime-database

我已经在ViewController类的开头声明了requestPostArray。我正在尝试从数据库“Request Posts”填充requestPostArray,然后从requestPostArray填充tableView。但是,当我打印它的大小时,它显示为0.任何帮助都将不胜感激。

另外,下面的整个else语句都在另一个闭包内。

else {

            ref.child("Request Posts").observe(.value, with: { (snapshot) in
                let count = Int(snapshot.childrenCount)

                // Request Post database is empty
                if count == 0 {
                    cell.nameLabel.text = "No requests so far."
                    cell.userNameLabel.isHidden = true
                    cell.numberOfRequestsLabel.isHidden = true
                }

                // Request Post data is populated
                else {

                    var requestPostArray: [RequestPost]? = []
                    self.ref.child("Request Posts").observe(.value, with: { (snapshot) in
                        if let result = snapshot.children.allObjects as? [FIRDataSnapshot] {

                            for child in result {
                                let post = RequestPost(snapshot: child)
                                requestPostArray?.append(post)
                            }
                        }

                        else {
                            print("No Result")
                        }
                    })


                    print("RequestPostArray size = \(requestPostArray?.count ?? 90)")

                    cell.nameLabel.text = self.requestPostArray?[indexPath.row].name
                    cell.userNameLabel.text = self.requestPostArray?[indexPath.row].name
                    cell.numberOfRequestsLabel.text = self.requestPostArray?[indexPath.row].name
                }
            })
        }

2 个答案:

答案 0 :(得分:3)

observe块是异步的。您在requestPostArray行修改之前正在阅读requestPostArray?.append(post)

如果没有更多的上下文,很难知道如何在这个cell对象上填充值,但如果你需要“请求帖子”,那么你必须等到你能够获得它们。

答案 1 :(得分:1)

这是应该发生的事情,因为observe函数是异步的,其余的代码是同步的,此外如果从requestPostArray?中删除可选的unwrap,你会得到一个nil异常,因为async任务需要时间来获取执行所以编译器将在它之前执行snyc任务。 基本上你要做的是以下

 else {

                ref.child("Request Posts").observe(.value, with: { (snapshot) in
                    let count = Int(snapshot.childrenCount)

                    // Request Post database is empty
                    if count == 0 {
                        cell.nameLabel.text = "No requests so far."
                        cell.userNameLabel.isHidden = true
                        cell.numberOfRequestsLabel.isHidden = true
                    }

                    // Request Post data is populated
                    else {

                        var requestPostArray: [RequestPost]? = []
                        self.ref.child("Request Posts").observe(.value, with: { (snapshot) in
                            if let result = snapshot.children.allObjects as? [FIRDataSnapshot] {

                                for child in result {
                                    let post = RequestPost(snapshot: child)
                                    requestPostArray?.append(post)
                                }
                            }

                            else {
                                print("No Result")
                            }
print("RequestPostArray size = \(requestPostArray?.count ?? 90)")

                        cell.nameLabel.text = self.requestPostArray?[indexPath.row].name
                        cell.userNameLabel.text = self.requestPostArray?[indexPath.row].name
                        cell.numberOfRequestsLabel.text = self.requestPostArray?[indexPath.row].name
                        })



                    }
                })
            }

另一个建议考虑使用单例,这样你就可以获得对象的重用,并且你不会像现在这样以同样的方法多次调用数据库。