'How to fix memory issues given by Instrument tools in Swift?

I have memory issues, especially for the error

XPC connection interrupted

The screen is freezing for a few seconds..

So, I've been learning how to use the Instruments tools and try to fix this error. However, I've been trying to find the error in my code and it's apparently not the fault of my code but maybe the libraries?

As a result of this test, I've got some warnings (the purple ones):

Memory Issues (3 leaked types):
- 1 instance of _DateStorage leaked (0x10b1eb060)
- 1 instance of OS_dispatch_data leaked (0x10b0b1ac0)
- 1 32-byte malloc block leaked (x10b1eb040)

Could you tell me how to fix these warnings, knowing there is no backtrace available? Or how could I find somewhere that could tell me to fix those?

EDIT:

Thanks to Instrument tools, I found the function that caused the problem! So, I don't know if it is really about memory or Idk but here's the function!

The accurate and useful error I get is : "Closure #1 in closure #1 in MessagesTableViewController.getLastMessages"

I found here What is a closure #1 error in swift?, the error is probably caused by forced optional types. So, I am going to try to remove those.

func getLastMessages(cell: ContactMessageTableViewCell, index: IndexPath) {

    // first, we get the total number of messages in chatRoom

    var numberOfMessagesInChatRoom = 0

    let previousCellArray = self.tableView.visibleCells as! [ContactMessageTableViewCell]

    var index1 = 0

    var messages = [JSQMessage]()

    var sortedMessages = [JSQMessage]()

    var messagesSortedByChatRooms = [String: [JSQMessage]]()

    var doesHaveMessagesCount = false

    var doesHaveSortedMessagesCount = false

    let firstQuery = Constants.refs.databaseChats.queryOrderedByKey()

    _ = firstQuery.observe(.childAdded, with: { [weak self] snapshot in

        if  let data        = snapshot.value as? [String: String],
            let id          = data["sender_id"],
            let name        = data["name"],
            let text        = data["text"],
            let chatRoom    = data["chatRoom"],
            !text.isEmpty
        {

            if let message = JSQMessage(senderId: id, displayName: name, text: text)
            {

                messages.append(message)

                var arrayVariable = [JSQMessage]()

                // we wanna get all messages and put it in the array corresponding to the chat room key

                if messagesSortedByChatRooms[chatRoom] != nil { // if there is already the chatRoom key in dictionary

                    if let message1 = messagesSortedByChatRooms[chatRoom] {
                        arrayVariable = message1
                    }

                    arrayVariable.append(message)

                    messagesSortedByChatRooms[chatRoom] = arrayVariable
                } else { // if there isn't the chatRoom key
                    arrayVariable.append(message)

                    messagesSortedByChatRooms[chatRoom] = arrayVariable
                }
            }
        }

        DispatchQueue.main.async {
            // we have to sort messages by date
            for (chatRoom, messagesArray) in messagesSortedByChatRooms {
                var loopIndex = 0

                var lastMessage: JSQMessage?

                var array = [JSQMessage]()

                for message in messagesArray { // we run through the messages array
                    array.removeAll()
                    loopIndex += 1

                    if loopIndex != 1 {
                        if message.date > lastMessage!.date {
                            array.append(message)

                            messagesSortedByChatRooms[chatRoom] = array
                        } else {
                            array.append(lastMessage!)

                            messagesSortedByChatRooms[chatRoom] = array
                        }
                    } else {
                        lastMessage = message

                        if messagesArray.count == 1 {
                            array.append(message)

                            messagesSortedByChatRooms[chatRoom] = array
                        }
                    }
                }
            }

            if !doesHaveMessagesCount {
                //doesHaveMessagesCount = true

                // we have the number of chats in database

                let secondQuery = Constants.refs.databaseChats.queryOrderedByPriority()

                _ = secondQuery.observe(.childAdded, with: { [ weak self] snapshot in

                    if  let data        = snapshot.value as? [String: String],
                        let id          = data["sender_id"],
                        let name        = data["name"],
                        let text        = data["text"],
                        let chatRoom    = data["chatRoom"],
                        !text.isEmpty
                    {

                        if let message = JSQMessage(senderId: id, displayName: name, text: text)
                        {

                            index1 += 1

                            if chatRoom != nil {

                                if let unwrappedSelf = self {

                                    if unwrappedSelf.sortedChatRoomsArray.contains(chatRoom) {

                                        sortedMessages.append(message)

                                        for (chatRoomKey, messageArray) in messagesSortedByChatRooms {

                                            unwrappedSelf.lastMessages[chatRoomKey] = messageArray[0]

                                        }

                                    }

                                }

                            }

                            if let unwrappedSelf = self {

                                if index1 == messages.count && chatRoom != unwrappedSelf.roomName {

                                    sortedMessages.append(JSQMessage(senderId: id, displayName: name, text: "no message"))

                                }


                            }

                        }

                    }

                    DispatchQueue.main.async {

                        if let unwrappedSelf = self {

                            if !doesHaveSortedMessagesCount {

                                //doesHaveSortedMessagesCount = true

                                if unwrappedSelf.sortedChatRoomsArray.indices.contains(index.row) {

                                    if unwrappedSelf.lastMessages[unwrappedSelf.sortedChatRoomsArray[index.row]] != nil {

                                        if unwrappedSelf.lastMessagesArray.count != 0 {

                                            let currentChatRoom = unwrappedSelf.sortedChatRoomsArray[index.row]

                                            if unwrappedSelf.lastMessages[unwrappedSelf.sortedChatRoomsArray[index.row]]?.text != "no message" {

                                                if UUID(uuidString: unwrappedSelf.lastMessages[unwrappedSelf.sortedChatRoomsArray[index.row]]!.text) == nil {

                                                    cell.contactLastMessageLabel.text = unwrappedSelf.lastMessages[unwrappedSelf.sortedChatRoomsArray[index.row]]?.text

                                                } else {

                                                    cell.contactLastMessageLabel.text = "New image"

                                                }

                                            } else {

                                                cell.contactLastMessageLabel.text = ""

                                                cell.contactLastMessageLabel.font = UIFont(name:"HelveticaNeue-Light", size: 16.0)

                                            }

                                            if unwrappedSelf.lastMessagesArray.indices.contains(index.row) {

                                                if unwrappedSelf.lastMessagesArray[index.row] != unwrappedSelf.lastMessages[unwrappedSelf.sortedChatRoomsArray[index.row]]?.text {

                                                    if unwrappedSelf.lastMessages[unwrappedSelf.sortedChatRoomsArray[index.row]]?.senderId != PFUser.current()?.objectId {

                                                        if unwrappedSelf.lastMessages[unwrappedSelf.sortedChatRoomsArray[index.row]]?.text != "no message" {

                                                            cell.contactLastMessageLabel.font = UIFont(name:"HelveticaNeue-Bold", size: 16.0)

                                                        }

                                                        var numberOfDuplicates = 0

                                                        for cell in previousCellArray {

                                                            if cell.contactLastMessageLabel.text == unwrappedSelf.lastMessages[unwrappedSelf.sortedChatRoomsArray[index.row]]?.text {

                                                                numberOfDuplicates += 1

                                                            }

                                                        }

                                                        if numberOfDuplicates == 0 {

                                                            if unwrappedSelf.selectedUserObjectId != "" {

                                                                unwrappedSelf.changeCellOrder(index: index.row, selectedUserObjectId: unwrappedSelf.selectedUserObjectId, lastMessage: unwrappedSelf.lastMessages[unwrappedSelf.sortedChatRoomsArray[index.row]]!.text)

                                                            } else {

                                                                unwrappedSelf.changeCellOrder(index: index.row, selectedUserObjectId: "none", lastMessage: unwrappedSelf.lastMessages[unwrappedSelf.sortedChatRoomsArray[index.row]]!.text)

                                                            }

                                                        } else {

                                                            unwrappedSelf.tableView.reloadData()

                                                        }

                                                        cell.activityIndicatorView.stopAnimating()

                                                    }

                                                } else {

                                                    cell.contactLastMessageLabel.font = UIFont(name:"HelveticaNeue-Light", size: 16.0)

                                                }

                                            }

                                        }

                                    } else {


                                    }

                                }

                            }


                        }

                    }

                })

            }

        }

    })

}

FINL EDIT: I put a closure inside of another closure so it created an infine loop ;)



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source