清楚 RxDataSources 中 SectionModelType 的“Self”要求的初始化

Clarity on init with `Self` requirement of SectionModelType in RxDataSources

将分段 table 与 RxDataSources using a TableViewSectionedDataSource, requires sections which conform to SectionModelType 绑定。

SectionModelType 协议具有以下初始化程序作为其要求之一:

    init(original: Self, items: [Item])

此外,同样的协议强制执行 var items: [Item] { get }。我们现在可以使用作为初始参数传递的 from original.itemsitems 初始化项目数组支持变量(在上面提到的 init 中)。这非常令人困惑。 SectionModelType 代码没有注释。

自述文件的

How 部分解释了为这种情况创建部分,讨论了创建类型别名(用于关联值)和项目数组,但没有提及以下 [=13= 的实现] original: Self :

init(original: SectionOfCustomData, items: [Item]) {
    self = original
    self.items = items
}

虽然这可以在结构中工作,但在 class 大喊中做同样的事情:

Cannot assign to value: 'self' is immutable

任何人都可以解释这里发生了什么以及为什么我们需要用 Self

初始化

最后,是否有另一种(更干净的)方式来反应性地(仅在 RXSwift / RxCocoa 中)将分段 table 视图绑定到可观察数据源。 例如 * 我的单元格和部分有自己的数据模型,需要 mutable(因此 classes) * 有多个屏幕对不同的实体有这种要求,所以我很想用协议来实现这一点,并用协议拍打相应的数据模型,并且有一个通用的 RXBinding

实现

任何指向更清楚地了解现有实施或实现上述要点的指示都会非常有帮助。 P.S.: 我已经在一个使用 Rx 的庞大代码库中工作,所以不使用 Rx 或迁移到 SwiftUI 等都不是我想要的。

init(original:items:) 是一个 copy 初始值设定项。它采用结构的一个已经存在的实例并创建一个相同的新实例,只是它更改了 items 属性.

中的内容

因此在协议声明中,init(original: Self, items: [Item]) 表示:"You hand me an already existing instance of whatever this type is that is conforming to me, the protocol, and we'll make a new instance that copies it while changing its items."

这正是示例所做的。把它们放在一起更容易看,像这样:

protocol SectionModelType {
    associatedtype Item
    var items: [Item] { get }
    init(original: Self, items: [Item])
}
struct CustomData {
    var anInt: Int
    var aString: String
    var aCGPoint: CGPoint
}
struct SectionOfCustomData {
    var header: String
    var items: [Item]
}
extension SectionOfCustomData: SectionModelType {
    typealias Item = CustomData
    init(original: SectionOfCustomData, items: [Item]) {
        self = original
        self.items = items
    }
}

这取决于你,在你的扩展实现中,做他们所做的:将 self 设置为 original,这是一些已经存在的 SectionOfCustomData 对象(在结构中允许initializer) 然后改变它的 items。而且你必须做那样的事情,并按那个顺序,因为如果你不这样做,你会试图初始化一个 SectionOfCustomData 对象而不设置它的 header 属性 — 然而,通过这种方式,我们可以保证 已经 一个 header 属性 值,因为我们从一个已经存在的 SectionOfCustomData 对象开始,如果不设置 header 属性.

,就无法制作

至于您的另一个担心,如果这是 class,而不是结构,则不会编译:是的,您完全正确,但不要那样做。这不是他们说要做的。他们说把它变成一个结构,他们是认真的。