Невозможно связать переменные V C с переменными, полученными в методе - PullRequest
0 голосов
/ 17 января 2020

В ViewController я установил две переменные с именами post и user соответственно типа Post и aUser , два созданных мной типа, которые содержат всю необходимую информацию.

Метод ViewDidLoad в V C выглядит следующим образом:

override func viewDidLoad() {
        super.viewDidLoad()
        updateViewDetail()
    }

Вызывает метод updateViewDetail (), который извлекает правильного пользователя и публикует объект из базы данных Firebase Realtime:

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 = post и self.user = user не работают должным образом и не равны переменной V C той, которая извлекается в методе. Знаете ли вы, как я могу решить эту проблему?

EDIT 1: переменные user и post , установленные внутри ViewController, используются для установки значений в UITableView с использованием пользовательский UITableViewCell. Код здесь: 1) сначала я установил tableViewDatasource равным ViewController.

override func viewDidLoad() {
        super.viewDidLoad()
        updateViewDetail(onUserRetrieved: { (user) in
            self.user = user
        }) { (post) in
            self.post = post
        }
       tableView.dataSource = self
    }

Затем я позволил V C соответствовать протоколу, установив необходимые методы:

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
    }

}

Когда я запускаю приложение, я получаю ошибку о том, что значения внутри post и пользователя HomeTableViewCell равны нулю, поэтому приложение вылетает.

1 Ответ

1 голос
/ 17 января 2020

Это потому, что пользователь и пост-извлечение являются асинхронными, поэтому вам нужно запустить их, как только данные будут готовы к использованию.

Я переписал вашу часть кода следующим образом:

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
}
...