如果 weak self 在 RxDataSource 函数中为 nil,我如何正确 return 一个带有 reuseIdentifier 的 CollectionViewCell?
How do I properly return a CollectionViewCell with reuseIdentifier if weak self is nil in RxDataSource function?
我遇到一个问题,由于内存泄漏,[unowned self] 在用于使用 RxDataSource 的 CollectionView 的 dataSource 函数中更改为 [weak self]。我现在收到了 returning 一个没有 reuseIdentifier 的空白 collectionViewCell 的崩溃。我了解我需要 return 具有 reuseID 的单元格。
建议进行哪些更改以正确处理此问题?
有人建议在 viewDidLoad() 中设置 collectionView.dataSource = nil 可以解决这个问题...
我在考虑 return 在 'guard' 检查中使用 CanvasItemCollectionViewCell(),而不是
我 return 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
}
}
崩溃:
最终,问题出在这里:
cell.onDeleteHandler = { _ in
self.presentDeleteConfirmation { deleteConfirmed in
guard deleteConfirmed else { return }
self.viewModel.inputs.deletePage(withProofID: model.id)
}
}
不要使用 self
并且你不会有 self 引用的问题所以你不需要导入一个 weak self 然后担心 guard let 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
}
}
我遇到一个问题,由于内存泄漏,[unowned self] 在用于使用 RxDataSource 的 CollectionView 的 dataSource 函数中更改为 [weak self]。我现在收到了 returning 一个没有 reuseIdentifier 的空白 collectionViewCell 的崩溃。我了解我需要 return 具有 reuseID 的单元格。
建议进行哪些更改以正确处理此问题?
有人建议在 viewDidLoad() 中设置 collectionView.dataSource = nil 可以解决这个问题...
我在考虑 return 在 'guard' 检查中使用 CanvasItemCollectionViewCell(),而不是 我 return 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
}
}
崩溃:
最终,问题出在这里:
cell.onDeleteHandler = { _ in
self.presentDeleteConfirmation { deleteConfirmed in
guard deleteConfirmed else { return }
self.viewModel.inputs.deletePage(withProofID: model.id)
}
}
不要使用 self
并且你不会有 self 引用的问题所以你不需要导入一个 weak self 然后担心 guard let 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
}
}