Проблема:
Я получаю утечки памяти в функции controllerDidChangeContent при профилировании моего приложения. Приборы говорит мне, что утечка должна быть в линии self.collectionView?.performBatchUpdates({ [unowned self] in
. Но как может быть цикл памяти, так как я уже добавил не принадлежащее мне, но безуспешно. Есть ли у вас какие-либо советы, как исправить эту утечку?
Идея:
Может ли это быть вызвано массивом private var blockOperations = [BlockOperation]()
, объявленным в классе? Но установить Array на слабое невозможно.
extension CollectionViewController: NSFetchedResultsControllerDelegate {
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.blockOperations = []
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any,
at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
var operation: BlockOperation
switch type {
case .insert:
guard let newIndexPath = newIndexPath else { return }
operation = BlockOperation { [unowned self] in
self.collectionView?.insertItems(at: [newIndexPath])
}
case .delete:
guard let indexPath = indexPath else { return }
operation = BlockOperation { [unowned self] in
self.collectionView?.deleteItems(at: [indexPath])
}
case .update:
guard let newIndexPath = newIndexPath else { return }
operation = BlockOperation { [unowned self] in
self.collectionView?.reloadItems(at: [newIndexPath])
}
case .move:
guard let indexPath = indexPath else { return }
guard let newIndexPath = newIndexPath else { return }
operation = BlockOperation { [unowned self] in
self.collectionView?.deleteItems(at: [indexPath])
self.collectionView?.insertItems(at: [newIndexPath])
}
}
blockOperations.append(operation)
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
// in the next line there is the leak shown in Instruments
self.collectionView?.performBatchUpdates({ [unowned self] in
for block in self.blockOperations {
block.start() }
}, completion: { [unowned self] _ in
self.blockOperations.removeAll()
})
updateView()
}
}