首页 > 解决方案 > 如何修复 NSFetchedResultsController controllerDidChangeContent 中的内存泄漏

问题描述

问题: 当我分析我的应用程序时,函数 controllerDidChangeContent 中出现内存泄漏。Instruments 告诉我泄漏应该在线路中self.collectionView?.performBatchUpdates({ [unowned self] in。但是既然我已经添加了无主的自我但没有成功,怎么会有记忆循环。您对如何解决此泄漏有任何提示吗?

想法: 这可能是通过private var blockOperations = [BlockOperation]()类中声明的数组引起的吗?但是不可能将数组设置为弱。

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()
}

}

标签: swiftclosuresautomatic-ref-countingnsblockoperation

解决方案


推荐阅读