[在ViewController中,我设置了两个分别称为Post和aUser的变量post
和user
,这是我创建的两个包含所有所需信息的类型。
VC的ViewDidLoad方法如下:
override func viewDidLoad() {
super.viewDidLoad()
updateViewDetail()
}
它调用updateViewDetail()方法,该方法从Firebase实时数据库中检索正确的用户并发布对象:
func updateViewDetail(){
Api.Post.observePost(with: postID) { (post) in
let postretrieved = post
print("post id inside \(postretrieved.caption)")
guard let postUid = postretrieved.uid else{
return
}
self.fetchUsers(uid: postUid) {
self.post = post
self.tableView.reloadData()
}
print("the post in the function : \(post.id)")
}
}
func fetchUsers(uid: String, completed: @escaping ()-> Void){
Api.theUser.observeUser(withID: uid) { (user) in
self.user = user
print("the user in the function is : \(user.id)")
completed()
}
}
方法的目标等于从数据库中检索到的帖子和用户等于我在ViewController中声明的帖子和用户,以便以后可以在TableView上显示它们。
问题是,当我尝试打印用户或在方法内部发布时(如代码所示),我看到正确的输出,可以正确地检索和打印用户。但是,当我尝试在viewDidLoad方法中打印它时,它将显示nil。
似乎self.post = post
和self.user = user
关联无法正常工作,并且不使VC变量等于该方法中检索到的VC变量。你知道我该怎么解决吗?
EDIT 1:在ViewController中设置的变量user和post用于使用自定义UITableViewCell设置UITableView中的值。代码在这里:1)首先,将tableViewDatasource设置为与ViewController相等。
override func viewDidLoad() {
super.viewDidLoad()
updateViewDetail(onUserRetrieved: { (user) in
self.user = user
}) { (post) in
self.post = post
}
tableView.dataSource = self
}
然后,我让VC遵循设置所需方法的协议:
extension DetailViewController : UITableViewDataSource{
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! HomeTableViewCell
cell.post = self.post
cell.user = self.user
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
}
[当我运行应用程序时,我得到一个错误,说内部和HomeTableViewCell用户的值均为零,因此该应用程序崩溃了。
那是因为用户和帖子检索是异步的,所以一旦数据准备好使用就需要被触发。
我已按如下方式重新编写了您的代码部分:
override func viewDidLoad() { super.viewDidLoad() updateViewDetail(onUserRetrieved: { user in print(user)}, onPostRetrieved: { post in print(post)}) } func updateViewDetail(onUserRetrieved: @escaping (User) -> Void, onPostRetrieved: @escaping (Post) -> Void ){ Api.Post.observePost(with: postID) { (post) in let postretrieved = post print("post id inside \(postretrieved.caption)") guard let postUid = postretrieved.uid else{ return } onPostRetrieved(post) self.fetchUsers(uid: postUid) { user in self.post = post onUserRetrieved(user) self.tableView.reloadData() } print("the post in the function : \(post.id)") } } func fetchUsers(uid: String, completed: @escaping (User)-> Void){ Api.theUser.observeUser(withID: uid) { (user) in self.user = user print("the user in the function is : \(user.id)") completed(user) } } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.post != nil && self.user != nil ? 1 : 0 }