Dwifft 和 ReactiveCocoa
Dwifft & ReactiveCocoa
我喜欢 Dwifft,但我更喜欢将它与 ReactiveCocoa 一起使用,以帮助进一步降低我的集合视图控制器中的代码复杂性。
目前,我有一个助手 class,它采用 SignalProducer<[[T]]>
的实例,其中 T: Equatable
(因此它适用于 differ)。每次信号生成器发出新值时:
self.data.producer.observeOn(UIScheduler()).on(next: { [unowned self] in
guard let collectionView = self.collectionView else { return }
for (index, element) in [=10=].enumerate() {
if index == self.diffCalculators.count {
let calculator = CollectionViewDiffCalculator<T>(collectionView: collectionView, initialRows: element)
calculator.sectionIndex = index
self.diffCalculators.append(calculator)
} else {
let calculator = self.diffCalculators[index]
calculator.rows = element
}
for index in self.data.value.count..<(self.diffCalculators.count >= self.data.value.count ? self.diffCalculators.count : self.data.value.count) {
self.diffCalculators.removeAtIndex(index)
}
}
})
.takeUntil(self.willDeallocSignal())
.start()
此处,在枚举我的二维数组时,如果差异计算器尚不存在,则会创建一个并将其添加到我的存储数组中,diffCalculators
。如果确实存在,则设置 rows
属性。之后,我遍历其余部分并将其删除。
不幸的是,我一直没有成功地让它发挥作用。一次又一次,我得到一个 The number of sections contained in the collection view after the update (1) must be equal to the number of sections contained in the collection view before the update (0), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).'
,但我不知道这是否符合我的逻辑,或者我是否使用了错误的 Dwifft。
有什么建议吗?
赏金编辑:
作为参考,这是我构建的用于将集合视图与反应性 cocoa 数据绑定在一起的助手 class:https://gist.github.com/startupthekid/b3a69363d83e2279da0d750959c5a930
我需要的是一种以反应式、线程安全的方式生成和修改 CollectionViewDiffCalculators
的方法。目前使用副作用崩溃取决于我接收新数据的速度(计算一个差异,数据进来,并且集合视图同时尝试重新加载)。
经过多次尝试和磨难,我发现问题实际上并不在我这边,而是在 Dwifft 的内部。 Dwifft 假设行将被设置一次,然后从那里开始,插入或删除。
但是当你用 ReactiveCocoa 绑定一个数组时,每次信号生成器发出时整个数组都会被覆盖,所以最终发生的是匹配的插入和删除将为单个发射生成。然后将尝试插入和删除项目,这就是崩溃的来源。
解决这个问题的方法是:
self.diffs <~ self.data.producer.combinePrevious([])
.map { Zip2Sequence([=10=].0, [=10=].1) }
.map { [=10=].map { [=10=].0.diff([=10=].1) } }
.on(next: { [weak self] in
let changes = [=10=].enumerate().map { index, diff in (diff.insertions.map({ NSIndexPath(forItem: [=10=].index, inSection: index) }), diff.deletions.map({ NSIndexPath(forItem: [=10=].index, inSection: index) })) }
let insertions = changes.map { [=10=].0 }.flatMap { [=10=] }
let deletions = changes.map { [=10=].1 }.flatMap { [=10=] }
if !Set(insertions).subtract(deletions).isEmpty {
self?.collectionView?.performBatchUpdates({
if !insertions.isEmpty { self?.collectionView?.insertItemsAtIndexPaths(insertions) }
if !deletions.isEmpty { self?.collectionView?.deleteItemsAtIndexPaths(deletions) }
}, completion: nil)
}
})
与 Dwifft 的内部结构基本相同,但增加了 if !Set(insertions).subtract(deletions).isEmpty { ... }
.
的检查
我喜欢 Dwifft,但我更喜欢将它与 ReactiveCocoa 一起使用,以帮助进一步降低我的集合视图控制器中的代码复杂性。
目前,我有一个助手 class,它采用 SignalProducer<[[T]]>
的实例,其中 T: Equatable
(因此它适用于 differ)。每次信号生成器发出新值时:
self.data.producer.observeOn(UIScheduler()).on(next: { [unowned self] in
guard let collectionView = self.collectionView else { return }
for (index, element) in [=10=].enumerate() {
if index == self.diffCalculators.count {
let calculator = CollectionViewDiffCalculator<T>(collectionView: collectionView, initialRows: element)
calculator.sectionIndex = index
self.diffCalculators.append(calculator)
} else {
let calculator = self.diffCalculators[index]
calculator.rows = element
}
for index in self.data.value.count..<(self.diffCalculators.count >= self.data.value.count ? self.diffCalculators.count : self.data.value.count) {
self.diffCalculators.removeAtIndex(index)
}
}
})
.takeUntil(self.willDeallocSignal())
.start()
此处,在枚举我的二维数组时,如果差异计算器尚不存在,则会创建一个并将其添加到我的存储数组中,diffCalculators
。如果确实存在,则设置 rows
属性。之后,我遍历其余部分并将其删除。
不幸的是,我一直没有成功地让它发挥作用。一次又一次,我得到一个 The number of sections contained in the collection view after the update (1) must be equal to the number of sections contained in the collection view before the update (0), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).'
,但我不知道这是否符合我的逻辑,或者我是否使用了错误的 Dwifft。
有什么建议吗?
赏金编辑:
作为参考,这是我构建的用于将集合视图与反应性 cocoa 数据绑定在一起的助手 class:https://gist.github.com/startupthekid/b3a69363d83e2279da0d750959c5a930
我需要的是一种以反应式、线程安全的方式生成和修改 CollectionViewDiffCalculators
的方法。目前使用副作用崩溃取决于我接收新数据的速度(计算一个差异,数据进来,并且集合视图同时尝试重新加载)。
经过多次尝试和磨难,我发现问题实际上并不在我这边,而是在 Dwifft 的内部。 Dwifft 假设行将被设置一次,然后从那里开始,插入或删除。
但是当你用 ReactiveCocoa 绑定一个数组时,每次信号生成器发出时整个数组都会被覆盖,所以最终发生的是匹配的插入和删除将为单个发射生成。然后将尝试插入和删除项目,这就是崩溃的来源。
解决这个问题的方法是:
self.diffs <~ self.data.producer.combinePrevious([])
.map { Zip2Sequence([=10=].0, [=10=].1) }
.map { [=10=].map { [=10=].0.diff([=10=].1) } }
.on(next: { [weak self] in
let changes = [=10=].enumerate().map { index, diff in (diff.insertions.map({ NSIndexPath(forItem: [=10=].index, inSection: index) }), diff.deletions.map({ NSIndexPath(forItem: [=10=].index, inSection: index) })) }
let insertions = changes.map { [=10=].0 }.flatMap { [=10=] }
let deletions = changes.map { [=10=].1 }.flatMap { [=10=] }
if !Set(insertions).subtract(deletions).isEmpty {
self?.collectionView?.performBatchUpdates({
if !insertions.isEmpty { self?.collectionView?.insertItemsAtIndexPaths(insertions) }
if !deletions.isEmpty { self?.collectionView?.deleteItemsAtIndexPaths(deletions) }
}, completion: nil)
}
})
与 Dwifft 的内部结构基本相同,但增加了 if !Set(insertions).subtract(deletions).isEmpty { ... }
.