【问题标题】:Cannot associate VC variables to ones retrieved in a Method无法将 VC 变量与在方法中检索到的变量相关联
【发布时间】:2020-05-04 09:50:34
【问题描述】:

在 ViewController 中,我设置了两个变量,分别称为 postuser,类型为 PostaUser,我创建的这两个类型包含所有需要的信息。

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 方法中打印它时,它打印为零。

self.post = postself.user = user 关联似乎无法正常工作,并且不等于 VC 变量与方法中检索到的变量相等。你知道我该如何解决这个问题吗?

编辑 1:在 ViewController 中设置的变量 userpost 用于使用自定义 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 的 post 和 user 中的值为零,因此应用程序崩溃了。

【问题讨论】:

  • 这可能是因为代码是异步运行的。
  • 您正在执行异步调用,因此viewDidLoad 中的打印语句在从 Firebase 返回数据之前执行。所以你的代码很可能运行良好。在 fetchUsers 中,尝试从 completed 闭包打印。
  • 这是一篇关于它的文章,What “asynchronous” means。对于社区来说,这个问题一直都在出现,是否有一个合适的问题可以作为重复问题的首选关闭?

标签: ios swift variables methods viewdidload


【解决方案1】:

那是因为用户和帖子检索是异步的,所以一旦数据准备好使用就需要触发。

我已将您的代码部分重写如下:

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
}

【讨论】:

  • 它可以工作,但是当我尝试用这些数据(帖子和用户)向 tableview 收费时仍然为零。我不明白为什么当数据刚刚被检索而不是之前,我如何在 tableview 上上传数据。
  • 能否展示tableview数据源函数与您核对?
  • 检查我在答复中的编辑以处理委托的行数。
  • 我试过了,但问题仍然存在。我认为问题在于为什么将 VC 的 post 和 user 属性传递给 tableViewDatasource 时为零。我假设 tableviewDataSource 在 VC 中设置 user 和 post 之前对数据收费。所以tableview收费数据时的变量为零。因此应用程序的运行崩溃。如何在设置数据(帖子和用户)之后加载 tableView?
  • 如果数据尚未准备好,此编辑将返回 0。因此,一旦您获得数据并重新加载 tsble 视图,此函数返回 1 以调用 cellForRow 函数并绘制单元格。 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.post != nil && self.user != nil ? 1 : 0 }
猜你喜欢
  • 2020-03-15
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 2013-10-10
  • 2012-12-10
  • 2015-11-02
  • 1970-01-01
相关资源
最近更新 更多