奇怪的tableView.reloadData()行为

时间:2018-12-11 13:42:49

标签: swift firebase firebase-realtime-database tableview

我正在尝试快速制作简单的Firebase实时聊天应用程序。我的数据库中有一个节点,存储未读消息的数量/

My database

我有一个自定义的tableview单元格,该单元格具有用于显示未读消息数的标签

 class UserCell: UITableViewCell {

var message: Message? {
    didSet {
        setNumberOfUnreadMessages()
}

fileprivate func setNumberOfUnreadMessages() {
    if let partnerId = message?.chatPartnerId(), let selfId = message?.selfId() {

        let unreadMessagesRef = Database.database().reference().child("unread-messages").child(selfId).child(partnerId).child("numberOfUnreadMessages")
        unreadMessagesRef.observe(.value, with: { (snapshot) in
            if let count = snapshot.value as? Int {
                self.unreadMessagesCountLabel.isHidden = false
                self.unreadMessagesCountLabel.text = String(count)
            } else {
                self.unreadMessagesCountLabel.isHidden = true
            }
            print(snapshot)
        }, withCancel: nil)
    }
}

我的tableView

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as? UserCell
        let message = messages[indexPath.row]
        cell?.message = message
        return cell!
    }


func observeUserMessages() {
    guard let uid = Auth.auth().currentUser?.uid else { return }
    // getting reference to current user's node
    let ref = Database.database().reference().child("user-messages").child(uid)
    ref.observe(.childAdded, with: { (snapshot) in
        let userId = snapshot.key
        // getting reference to partners node in user's node
        let userMessagesRef = Database.database().reference().child("user-messages").child(uid).child(userId)
        userMessagesRef.observe(.childAdded, with: { (snapshot) in
            if let dictionary = snapshot.value as? [String:AnyObject] {
                let message = Message(dictionary: dictionary)
                if let chatPartnerId = message.chatPartnerId() {
                    self.messagesDictionary[chatPartnerId] = message
                }
                self.attemptReloadOfTableView()
            }
        }, withCancel: nil)
    }, withCancel: nil)
    ref.observe(.childRemoved, with: { (snapshot) in
        print(snapshot.key)
        self.messagesDictionary.removeValue(forKey: snapshot.key)
        self.attemptReloadOfTableView()
    }, withCancel: nil)
}


// Big thank to Brian Woong)))))
var timer: Timer?

private func attemptReloadOfTableView() {
    self.timer?.invalidate()
    self.timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.handleReloadTableView), userInfo: nil, repeats: false)
}

@objc func handleReloadTableView() {
    self.messages = Array(self.messagesDictionary.values)
    self.messages.sort(by: { (message1, message2) -> Bool in
        return (message1.timeStamp?.intValue)! > (message2.timeStamp?.intValue)!
    })
    DispatchQueue.main.async {
        self.tableView.reloadData()
    }
}

启动我的应用程序时,每个tableView.cell都会显示来自数据库的正确未读消息数。当我开始发送消息时,tableView重新加载并开始显示发件人未读消息的数量,不仅在他的单元格上,而且在所有单元格上。此外,在控制台中,我看到它会在每条即将到来的消息中从数据库获取越来越多的快照。

会发生什么?如何解决这个奇怪的错误?

1 个答案:

答案 0 :(得分:0)

 let unreadMessagesRefHandle = unreadMessagesRef.observe(.value, with: { (snapshot) in
            if let count = snapshot.value as? Int {
                self.unreadMessagesCountLabel.isHidden = false
                self.unreadMessagesCountLabel.text = String(count)
            } else {
                self.unreadMessagesCountLabel.isHidden = true
            }
            print(snapshot)
        }, withCancel: nil)
        unreadMessagesRef.removeObserver(withHandle: unreadMessagesRefHandle)