假设我们有一个用Swift编写的代码,它使用合并:
import UIKit
import Combine
class Test {
@Published var array: [Int] = [] {
willSet {
print("willSet \(newValue.count)")
}
didSet {
print("didSet \(array.count)")
}
}
}
var test = Test()
var subscriber = test.$array.sink { values in
print("arrayCount: \(test.array.count) valuesCount: \(values.count)")
}
print("1 arrayCount \(test.array.count)")
test.array = [1, 2, 3]
print("2 arrayCount \(test.array.count)")
test.array = [1]
print("3 arrayCount \(test.array.count)")
此代码在控制台上打印以下结果(可以在playground中快速测试):
arrayCount: 0 valuesCount: 0
1 arrayCount 0
willSet 3
arrayCount: 0 valuesCount: 3
didSet 3
2 arrayCount 3
willSet 1
arrayCount: 3 valuesCount: 1
didSet 1
3 arrayCount 1
正如我们所看到的,给sink方法的代码在willSet之后和didSet之前执行。现在我的问题是是否有任何方法可以创建这个发布者或订阅它,以使给sink的代码在didSet之后执行而不是在didSet之前执行(这样在上面的示例中执行print from sink时arrayCount和valuesCount将是相同的)?
3条答案
按热度按时间czfnxgou1#
Published.Publisher
使用willSet
发出 Package 属性的值。不幸的是,您无法改变这种行为,唯一的解决方案是实现您自己的属性 Package 器,使用didSet
而不是willSet
。您还可以使用
emitCurrentValue
输入参数自定义是否希望在订阅projectValue
发布者时接收当前值(匹配@Published
行为)。如果设置为true
,则当前wrappedValue
将在订阅时发送给新订阅者。你可以像观察
@Published
一样观察@PostPublished
。but5z9lq2#
首先,如果目的是让发布者在didSet上发出事件,那么您可以简单地使用
CurrentValueSubject
。它的语法不像@Published
那么漂亮,但它确实做到了这一点:如果您已经有一个想要保留的
@Published
变量(例如,您的SwiftUI视图使用了它),但您还希望在它们发生后观察更改,那么您可以添加一个CurrentValueSubject
并在didSet
中更新它然后以大致相同的方式观察数组:
arrayChangedEvent.sink { /* ... */ }
jjjwad0x3#
我会说用一个简单的黑客