首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UITableViewDiffableDataSource不重要

UITableViewDiffableDataSource不重要
EN

Stack Overflow用户
提问于 2021-12-19 18:02:44
回答 1查看 357关注 0票数 1

我想在我的项目中使用联合收割机,并面对这个问题。以下是ViewController的代码

代码语言:javascript
复制
import Combine
import UIKit

class ProfileDetailsController: ViewController {
    //

    // MARK: - Views
    @IBOutlet private var tableView: UITableView!

    // MARK: - Properties
    private typealias DataSource = UITableViewDiffableDataSource<ProfileDetailsSection, ProfileDetailsRow>
    private typealias Snapshot = NSDiffableDataSourceSnapshot<ProfileDetailsSection, ProfileDetailsRow>

    @Published private var data: [ProfileDetailsSectionModel] = {
        return ProfileDetailsSection.allCases.map { ProfileDetailsSectionModel(section: $0, data: $0.rows) }
    }()
    
    private lazy var dataSource: DataSource = {
        let dataSource = DataSource(tableView: tableView) { tableView, _, model in
            let cell = tableView.dequeueReusableCell(withIdentifier: TextFieldTableCell.name) as! TextFieldTableCell
            cell.delegate = self
            cell.setData(model: model)
            return cell
        }
        dataSource.defaultRowAnimation = .fade
        return dataSource
    }()
}

// MARK: - Setup binding
extension ProfileDetailsController {
    override func setupBinding() {
        tableView.registerCellXib(cell: TextFieldTableCell.self)
        $data.receive(on: RunLoop.main).sink { [weak self] models in
            let sections = models.map { $0.section }
            var snapshot = Snapshot()
            snapshot.appendSections(sections)
            models.forEach { snapshot.appendItems($0.data, toSection: $0.section) }
            self?.dataSource.apply(snapshot, animatingDifferences: true)
        }.store(in: &cancellable)
    }
}

// MARK: - Cell delegates
extension ProfileDetailsController: TextFieldTableCellDelegate {
    func switcherAction() { }
}

这是牢房的密码。

代码语言:javascript
复制
import UIKit

protocol TextFieldTableCellData {
    var placeholder: String? { get }
}

protocol TextFieldTableCellDelegate: NSObjectProtocol {
    func switcherAction()
}

class TextFieldTableCell: TableViewCell {
    //

    // MARK: - Views
    @IBOutlet private var textField: ZWTextField!

    // MARK: - Properties
    public weak var delegate: TextFieldTableCellDelegate?

    override class var height: CGFloat {
        return 72
    }
}

// MARK: - Public method
extension TextFieldTableCell {
    func setData(model: TextFieldTableCellData) {
        textField.placeholder = model.placeholder
    }
}

未调用ViewController的deinit。但是当我把这段代码用于ViewController时

代码语言:javascript
复制
import UIKit

class ProfileDetailsController: ViewController {
    //

    // MARK: - Views
    @IBOutlet private var tableView: UITableView!

    // MARK: - Properties
    @Published private var data: [ProfileDetailsSectionModel] = {
        return ProfileDetailsSection.allCases.map { ProfileDetailsSectionModel(section: $0, data: $0.rows) }
    }()
}

// MARK: - Startup
extension ProfileDetailsController {
    override func startup() {
        tableView.dataSource = self
        tableView.registerCellXib(cell: TextFieldTableCell.self)
    }
}

// MARK: - Startup
extension ProfileDetailsController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return data.count
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data[section].data.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let model = data[indexPath.section].data[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: TextFieldTableCell.name) as! TextFieldTableCell
        cell.delegate = self
        cell.setData(model: model)
        return cell
    }
}

// MARK: - Cell delegates
extension ProfileDetailsController: TextFieldTableCellDelegate {
    func switcherAction() {}
}

百事大吉。deinit打电话来了。我尝试将dataSource设置为可选,并在deinit上设置为零,结果相同。只有当我评论这一行时,才会调用Combine:

代码语言:javascript
复制
cell.delegate = self

有人知道怎么回事吗?Xcode 13.2 iOS 15.2

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-19 18:19:38

这种组合物完全是一种红鲱鱼。这就是你找不到问题的原因,你找错地方了。问题在于老式数据源和可扩展数据源之间的区别。问题在于:

代码语言:javascript
复制
private lazy var dataSource: DataSource = { // *
    let dataSource = DataSource(tableView: tableView) { tableView, _, model in
        let cell = tableView.dequeueReusableCell(withIdentifier: TextFieldTableCell.name) as! TextFieldTableCell
        cell.delegate = self // *

我主演了有问题的台词:

一方面,您(视图控制器,dataSource. )保留了

另一方面,您正在为数据源提供一个单元格提供程序函数,您在其中谈到了self.。

这是一个保留周期!你得打破这个循环。变化

代码语言:javascript
复制
let dataSource = DataSource(tableView: tableView) { tableView, _, model in

代码语言:javascript
复制
let dataSource = DataSource(tableView: tableView) { [weak self] tableView, _, model in

(这将编译,因为尽管self现在是可选的,但cell.delegate也是可选的。)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70414035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档