【问题标题】:viewDidLoad, is it called only once?viewDidLoad,它只调用一次吗?
【发布时间】:2017-10-09 12:34:00
【问题描述】:

我是 iOS 开发的初学者,我正在学习一个使用 firebase 数据库制作简单聊天应用程序的教程。其实我对viewDidLoad方法的使用感到困惑。

这是应用的截图:https://ibb.co/gqD4Tw

我不明白为什么当我想将数据(聊天消息)发送到 firebase 数据库时,为什么在 viewDidLoad 上使用 retrieveMessage() 方法,我使用了 sendButtonPressed() 方法(这是一个 IBAction),当我想从数据库中检索数据,我使用retrieveMessage()

retrieveMessage() 方法在viewDidLoad 上调用,据我所知viewDidLoad 方法在视图加载到内存后只调用一次。我们通常使用它进行初始设置。

那么,如果viewDidLoad在初始设置中只被调用一次,为什么retrieveMessage()方法可以在我将消息数据发送到数据库之后一遍又一遍地检索我发送到我自己的数据库的所有消息?

我不明白为什么retrieveMessage()方法放在viewDidLoad下面是简化代码:

class ChatViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {


    var messageArray = [Message]()

    @IBOutlet var messageTextfield: UITextField!
    @IBOutlet var messageTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        //Set as the delegate and datasource :
        messageTableView.delegate = self
        messageTableView.dataSource = self

        //the delegate of the text field:
        messageTextfield.delegate = self

        retrieveMessage()

        ///////////////////////////////////////////

    //MARK: - Send & Recieve from Firebase

    @IBAction func sendPressed(_ sender: AnyObject) {

    // Send the message to Firebase and save it in our database

    let messageDB = FIRDatabase.database().reference().child("message")
    let messageDictionary = ["MessageBody":messageTextfield.text!, "Sender": FIRAuth.auth()?.currentUser?.email]

        messageDB.childByAutoId().setValue(messageDictionary) {
            (error,ref) in

            if error != nil {
                print(error!)
            } else {
                self.messageTextfield.isEnabled = true
                self.sendButton.isEnabled = true
                self.messageTextfield.text = ""
            }   
        }
    }

    //Create the retrieveMessages method :

    func retrieveMessage () {
        let messageDB = FIRDatabase.database().reference().child("message")

        messageDB.observe(.childAdded, with: { (snapshot) in

            let snapshotValue = snapshot.value as! [String:String]

            let text = snapshotValue["MessageBody"]!
            let sender = snapshotValue["Sender"]!

            let message = Message()
            message.messsageBody = text
            message.sender = sender

            self.messageArray.append(message)

            self.messageTableView.reloadData()
        })
    }
}

【问题讨论】:

  • 因为您在该方法中添加了观察者,也就是说,如果您添加消息,那么它会自动反映
  • retrieveMessage 函数中有一个observe 闭包,从该闭包中messageArraymessageTableView 得到更新。所以在viewDidLoad你只开始观察,从那时起观察者不断更新你的数据和UI。
  • 我明白了。谢谢:)

标签: ios swift firebase firebase-realtime-database


【解决方案1】:

viewDidLoad 方法在 ViewController 生命周期中只调用一次。

之所以在viewDidLoad 中调用retrieveMessage(),是因为它添加了观察者以开始侦听接收和发送的消息。一旦您收到或发送消息,就会调用此块(观察者)并 然后将该文本添加到数组self.messageArray.append(message) 中并更新tableview。

【讨论】:

    【解决方案2】:

    viewDidLoad 只被调用一次,但 firebase 函数会启动一个监听器,在后台工作并同步数据。 它在 viewDidLoad 中被调用,因为它告诉 -> 当这个视图加载时,开始监听消息。

    【讨论】:

      【解决方案3】:

      ViewDidLoad() 仅在初始化 ViewController 时调用。 如果您想在每次用户再次查看 VC 时调用一个函数(例如,在从另一个 VC 转回之后),您可以使用 ViewDidAppear()。 在调用ViewDidLoad() 时也会调用它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多