首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >何时在tableView单元中分离防火墙侦听器?

何时在tableView单元中分离防火墙侦听器?
EN

Stack Overflow用户
提问于 2018-10-15 09:14:17
回答 2查看 285关注 0票数 0

在聊天应用程序中,为了跟踪每个聊天用户的最后消息和未读消息,当tableView单元退出队列时,我将在单元上附加一个.childChanged侦听器。当侦听器被触发时,我将更新每一行的chat label.text,以便进行相应的聊天。

什么时候应该删除这些侦听器,或者在我的情况下更新单元格中的聊天的最佳实践是什么?

程序的流程是什么?

  1. 下载当前用户
  2. 下载当前用户聊天
  3. 下载每个chatID的聊天
  4. 用聊天填充tableView
  5. 在每个细胞中观察childChanged chats/chat.chatUID/currentUserUID/.observe(.childChanged)
  6. 如果"unreadMessagesCount“被更改,请在单元格上更新它
代码语言:javascript
复制
class ChatTableViewCell: UITableViewCell {
  @IBOutlet weak var lastMessageLabel: UILabel!

    var chat: Chat! {
       didSet{
        self.updateUI()
     }
  }

  func updateUI() {

    self.chat.observeChildChanged(chat: self.chat, currentUserUID:user.userUID) { (lastMessage, unreadMessagesCount) in

        if !lastMessage.isEmpty{
            self.lastMessageLabel.text = lastMessage
        }

        if unreadMessagesCount > 0 {
            self.lastMessageLabel.font = UIFont.boldSystemFont(ofSize: 16.0)
            self.chatUnreadMessagesCount.text = "\(unreadMessagesCount)"
        } else {
            self.lastMessageLabel.font = UIFont.systemFont(ofSize: 15.0)
            self.chatUnreadMessagesCount.text = ""
        }
    }
  }
} 

 class MessagesViewController: UITableViewController {
     override func viewDidLoad() {
      //observe ~/users/uid
       DDatabaseRReference.users(uid: uid).reference().observeSingleEvent(of: .value, with: { (snapshot) in

        guard snapshot.exists() else {return}

            if let userDict = snapshot.value as? [String : Any] {
                self.currentUser = UserModel(dictionary: userDict)
                self.userWasDownloaded = true //this will trigger the setter and start downloading chatId's of current user
            }
    })
 }

 var userWasDownloaded: Bool {
     get {
        return true
     }
     set {
        self.fetchChatsIdsOf(currentUser: self.currentUser)
        self.tableView.reloadData()
     }
 }


func fetchChatsIdsOf(currentUser: UserModel) {
     //get chatIds of currentUser from ~/users/currentUser.userUID/chatIds
    DDatabaseRReference.users(uid: currentUser.userUID).reference().child("chatIds").observe(.childAdded, with: { (snapshot) in

        let chatUID = snapshot.key
        if !self.chatIdsDownloaded.contains(chatUID) {
            self.chatIdsDownloaded.append(chatUID)
        }
    })
}

//after chatIdsDownloaded is set,
//download the new chat for the last chat appended to chatIdsDownloaded array
var chatIdsDownloaded = [String]() {
    didSet {
        guard let chatID = chatIdsDownloaded.last else  {return}
        self.downloadNewChat(chatID: chatID)
    }
}

    func downloadNewChat(chatID: String) {
   DDatabaseRReference.chats.reference().child(chatID).observeSingleEvent(of: .value, with: { (snapshot) in
        ......
      self.currentUserChats.insert(chatChecked, at: 0)
     }
   }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "ChatTableViewCell", for: indexPath) as! ChatTableViewCell
       cell.chat = currentUserChats[indexPath.row]
      return cell
    }
 } 



chats    // <- all chats in the app for all users in the app
 -LOMVtcjOEOu2p1apMKV
   chatUID: "-LOMVtcjOEOu2p1apMKV"
   isGroupChat: true
   lastMessage: "Katherine Gregory has joined the group"
   lastUpdate: 1539761870.2237191
   +users
     IN4pgCS5NqQZZLpdmoz1KeDiFqj2
     fcmToken: ""
     firstName: "Alex"
     userUID: "IN4pgCS5NqQZZLpdmoz1KeDiFqj2"
     unreadMessagesCount: 5



users   // <- all users in the app
 IN4pgCS5NqQZZLpdmoz1KeDiFqj2
   +chatIds
      -LOMVtcjOEOu2p1apMKV: true
      - name: ""
      - email: ""
       ...etc
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-29 12:37:01

正如杰伊建议的那样,我在新下载的每一次聊天中都附加了.childChanged观察者。

但是,如果我转到firebase控制台并在ref路径上更新子节点的值,则并不总是会触发childChanged观察者。有时,它有效,有时它不可能是什么问题?

我在所有的行上都使用断点,当数据库中的值被更改时,它们都不会被击中。

例子:name:“亚历克斯”

更改:姓名:"John“

更新

这个答案是正确的,我忘记删除我以前的实现,在这个实现中分离prepareForReuse()中的侦听器。

代码语言:javascript
复制
var currentUserChats = [Chat]() {
    didSet(newValue){
       attachChildChangedObserverOn(chat: newValue)
    }
}

var observersArray = [String: UInt]() // chatUID:handle


  func attachChildChangedObserverOn(chat: Chat) {

     var handle: UInt = 0
     let ref =   DDatabaseRReference.chats.reference().child(chat.chatUID).child("users").child(currentUser.userUID)
    handle = ref.observe(.childChanged, with: {[weak self] (snapshot) in

     self?.observersArray[chat.chatUID] = handle

        print("snapshot.value is \(snapshot.value) and snapKey is \(snapshot.key)")
        guard snapshot.exists() else {return}

        let chatChanged = chat

        var lastMessage = ""
        var unreadMessagesCount = 0
        var lastUpdate = 0.0

        switch snapshot.key {
        //case....
       }

     })

  }
票数 0
EN

Stack Overflow用户

发布于 2018-10-15 10:04:18

您可以检查是否为单元格添加了2个或更多的观察者。

在这里添加断点或print():

代码语言:javascript
复制
self.chat.observeChildChanged(chat: self.chat, currentUserUID: user.userUID) { (lastMessage, unreadMessagesCount) in {
   //breakpoint or print("observeChildChanged")
   ...
}

请重新使用你的手机。

发送新信息。

如果您有2条或更多条消息,这意味着您没有只设置一个观察者。

也许这种方法并不完美,但它可以帮助您(在添加新的之前删除旧的观察者):

代码语言:javascript
复制
var chat: Chat! {
   didSet {
      self.removeOldObserver()
      self.updateUI()
   }
}

func removeOldObserver() {
   ...
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52813356

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档