Просмотр коллекции становится все медленнее по мере того, как я вставляю в нее все больше и больше элементов

#ios #swift #performance #core-data #uicollectionview

#iOS #swift #Производительность #core-data #uicollectionview

Вопрос:

Итак, я создаю приложение для обмена сообщениями, используя JSQMessagesViewController. Я связал его с fetchedResultsController, который отслеживает каждый раз, когда я вставляю новый объект в контекст. В didPressSend я вставляю в контекст:

     override func didPressSend(_ button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: Date!) {
    let message = NSEntityDescription.insertNewObject(forEntityName: "Message", into: context) as! Message
    message.text = text
    message.timestamp = Date() as NSDate?


}
  

Поэтому каждый раз, когда я вставляю новый объект в контекст с помощью DidPressSend (кнопка отправки), запускается контроллер полученных результатов

 var InsertOperation = [BlockOperation]()
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    if type == .insert {

        InsertOperation.append(BlockOperation(block: { [weak self] in

            self?.collectionView.collectionViewLayout.invalidateLayout()
            self?.collectionView.insertItems(at: [newIndexPath!])
            DispatchQueue.main.async {
            self?.scrollToBottom(animated: true)
            }

            }))


    }



}
  

Затем операция блокировки выполняется в didChangeContent

 func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {

   collectionView.performBatchUpdates({ 
    for operation in self.InsertOperation {
    operation.start()
    self.InsertOperation.removeFirst()

    }
    })

}
  

Это, наконец, вставляет элемент в представление коллекции, которое было создано в didPressSend. Сначала он вставляет их с феноменальной скоростью. Все работает потрясающе!. Однако, когда я добираюсь до 100 или около того элементов в CollectionView, он начинает становиться все более и более вялым. У меня нет ничего необычного в моих методах делегирования CollectionView. Просто то, что требуется как таковое:

 override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageDataForItemAt indexPath: IndexPath!) -> JSQMessageData! {
    let msg : Message = fetchedResultsControler.object(at: indexPath) as! Message
    let messageData = JSQMessage(senderId: senderId, displayName: senderDisplayName, text: msg.text)
    return messageData
}


override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return (fetchedResultsControler.sections?[0].numberOfObjects)!
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell

    return cell
}


override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAt indexPath: IndexPath!) -> JSQMessageBubbleImageDataSource! {
    let bubbleFactory = JSQMessagesBubbleImageFactory()
    return bubbleFactory?.outgoingMessagesBubbleImage(with: .black)
}

override func collectionView(_ collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAt indexPath: IndexPath!) -> JSQMessageAvatarImageDataSource! {
    return nil
}
  

Я не включил это в код, но когда пользователь нажимает кнопку «Назад» и возвращается в чат, он разбивает чат на страницы, показывая только последние 20 сообщений, что снова делает его сверхбыстрым. Однако очень возможно, что пользователь может отправить много сообщений, прежде чем нажать «Назад» и предоставить просмотру коллекции возможность разбиения на страницы. В результате пользовательский опыт серьезно ухудшится, поскольку пользователь находится в чате. Я заметил, что в таких приложениях, как tinder (я тестировал это), вы можете отправлять 1000 сообщений одновременно, и ничто не замедлится. Должен быть трюк, который я не могу разгадать.
Спасибо!

Комментарии:

1.почему вы invalidate collectionView's размещаете каждый раз, когда отправляете сообщение?

2. Привет, Адил, я убрал это, так как только что понял, что на самом деле мне это вообще не нужно. Однако это не решает проблему производительности.