函数主体运行的次数与我介绍的ViewController一样多

时间:2019-03-26 20:57:47

标签: ios swift socket.io

我真的很困惑。

我在ViewController中具有监听服务器端发出的socket.io的功能。 在我第一次打开视图控制器并从服务器获取消息后,一切正常。 但是,当我第二次打开ViewController(使用present)并从服务器获取消息时,此方法实际上运行了两次,并且是我展示ViewController的次数。

我的功能是:

func sendMessageStatus() {
     var message_body: String!
     var send_time: String!
     var chat_user_id: UInt!
    let socket = SocketConfig.manager.defaultSocket
    socket.on("messageReceived") { (dataArray, ack) in
        let response = dataArray as NSArray
        for resp in response {
            let resp_dic = resp as! NSDictionary
            for z in resp_dic {
                if z.key as! String == "time_now" {
                    send_time = (z.value as! String)
                }
                if z.key as! String == "message_body" {
                    message_body = z.value as? String
                }
                if z.key as! String == "chat_id" {
                    chat_user_id = z.value as? UInt
                    self.chat_id = z.value as? UInt
                }
            }
        }
        // 0 user_id is the value for my id(i dont have my id and none of users id is 0 so i use this for know my messages)
        let message_object = Messages(user_id: 0, message: message_body, receive_time: send_time)
        if var items = messages_dic[chat_user_id] {
            items.append(message_object)
            messages_dic[chat_user_id] = items
        }
        else {
            messages_dic[chat_user_id] = [message_object]
        }
        self.chatTableview.reloadData()
        self.scrollToBottom(animated: true, delay: 0.3)
    }

}

并将其附加到我的messages_dic中的次数与显示ViewController的次数相同。

有人可以帮助解决这个问题吗? 谢谢。

3 个答案:

答案 0 :(得分:1)

很难说没有看到ViewController的代码,但是我猜想是否发出"messageReceived"的频率比您想象的要频繁。也许是document.ready()函数或其他函数。乍一看,这里的代码看起来还不错。

答案 1 :(得分:0)

正如一位评论者建议的那样,您可能存在内存泄漏。您的ViewController可能无法正确释放。

我建议在您的套接字闭包中使用[weak self]

socket.on("messageReceived") { [weak self] (dataArray, ack) in

然后在套接字闭包中,将self替换为self?。例如:

self?.chatTableview.reloadData()

答案 2 :(得分:0)

我发现了问题。

问题是每次我展示ViewController时 socket.on(“ messageReceived”) 再次设置并确保运行与我介绍ViewController一样多的次数。

因此,为了解决该问题,我使用套接字处理程序来检查是否再次处理了“ messageReceived”(设置socket.on)。 所以我用这段代码解决了问题。

    var is_set: Bool = false
    let socket = SocketConfig.manager.defaultSocket
    for handler in socket.handlers {
        if handler.event ==  "messageReceived" {
            is_set = true
        }
    }
    if !is_set { // so set that
    socket.on("messageReceived") { (dataArray, ack) in 
     // othere codes
  }

另一种方法是,当我关闭ViewController时,将通过以下代码删除所有处理程序:

 deinit() {
     let socket = SocketConfig.manager.defaultSocket
    socket.removeAllHandlers()
 }

希望能帮助别人。