【问题标题】:How do I properly return a CollectionViewCell with reuseIdentifier if weak self is nil in RxDataSource function?如果弱自我在 RxDataSource 函数中为零,我如何正确返回带有重用标识符的 CollectionViewCell?
【发布时间】:2021-08-27 00:03:30
【问题描述】:

我有一个问题,由于内存泄漏,在用于使用 RxDataSource 的 CollectionView 的 dataSource 函数中 [unowned self] 更改为 [weak self]。我现在收到了返回一个没有重用标识符的空白 collectionViewCell 的崩溃。我了解我需要返回一个带有重用 ID 的单元格。

建议进行哪些更改以正确处理此问题?

有人建议在 viewDidLoad() 中设置 collectionView.dataSource = nil 会解决这个问题...

我在想,而不是在“守卫”检查中返回 CanvasItemCollectionViewCell(), 我返回 collectionView.dequeueReusableCell(for: indexPath, cellType: CanvasItemCollectionViewCell.self),但是如果 self = self 失败,那不意味着 collectionView 是垃圾吗?

这是一个难以调试的问题,因为这种崩溃不会持续发生。

这里有一些截图来描述我正在查看的内容。

RxData源代码:

func dataSource()
        -> RxCollectionViewSectionedAnimatedDataSource<CanvasSectionModel> {
        RxCollectionViewSectionedAnimatedDataSource<CanvasSectionModel>(
            animationConfiguration: AnimationConfiguration(
                insertAnimation: .fade,
                reloadAnimation: .fade,
                deleteAnimation: .fade
            ),
            configureCell: { [weak self] dataSource, collectionView, indexPath, _ in
                guard let self = self else { return CanvasItemCollectionViewCell() }
                
                switch dataSource[indexPath] {
                case let .CellModel(model):
                    let cell = collectionView
                        .dequeueReusableCell(
                            for: indexPath,
                            cellType: CanvasItemCollectionViewCell.self
                        )

                    cell.model = model

                    cell.onDeleteHandler = { _ in
                        self.presentDeleteConfirmation { deleteConfirmed in
                            guard deleteConfirmed else { return }
                            self.viewModel.inputs.deletePage(withProofID: model.id)
                        }
                    }

                    return cell
                }
            }

崩溃

【问题讨论】:

    标签: ios uicollectionview uicollectionviewcell rx-swift rxdatasources


    【解决方案1】:

    归根结底,问题出在这里:

    cell.onDeleteHandler = { _ in
        self.presentDeleteConfirmation { deleteConfirmed in
            guard deleteConfirmed else { return }
            self.viewModel.inputs.deletePage(withProofID: model.id)
        }
    }
    

    不要使用self,你不会有自我引用的问题,所以你不需要导入一个弱自我,然后担心守卫让自我......

    • 对于第一个 self 引用,将其替换为 UIViewController.top()(参见下文以了解实现。)
    • 对于第二个 self 引用,请改为捕获 viewModel
    extension UIViewController {
        static func top() -> UIViewController {
            guard let rootViewController = UIApplication.shared.delegate?.window??.rootViewController else { fatalError("No view controller present in app?") }
            var result = rootViewController
            while let vc = result.presentedViewController, !vc.isBeingDismissed {
                result = vc
            }
            return result
        }
    }
    

    【讨论】:

    • 我最终只是将onDeleteHandler 的整个分配封装到一个闭包中,就像func dataSource(onDelete: @escaping (CanvasEntity)-&gt;() )cell.onDeleteHandler = { _ in onDelete(model) } 这样让我删除两个自引用。谢谢
    猜你喜欢
    • 2014-08-19
    • 1970-01-01
    • 2020-06-21
    • 2017-09-07
    • 2018-08-26
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多