Должно было остаться на некоторое время дольше - это возможно (хотя и не так, как Published
)
Следующий код обновляет приведенный выше код, добавляя тип Void
valueWillChange
Издатель, чтобы тот же поток работал. И я не осознавал, что в Swift встроено отражение с Mirror
.
Не могу сказать, что знаю, как ObservedObject
работает без всеобъемлющего протокола или несколько скрытого издателя для значения Void - или, возможно, как преобразовать его в Published<Value>
введите, не зная, что такое Value
(или игнорируя его)
Это также не составит труда адаптировать к любому другому условию, которое может потребоваться (меньше, чем проверка значения и т. д. c)
class Model: EqObservableObject {
@EqPublished var valueEq = 5
@Published var valueAlways = 5
}
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public class EqObservableObject : Combine.ObservableObject {
private var eqValuesChanging: [AnyCancellable] = []
init()
{
let mirror = Mirror(reflecting: self)
for child in mirror.children
{
if let value = child.value as? EqPublishedProtocol
{
eqValuesChanging.append(
value.valueWillChange.sink(receiveValue: { [weak self] in
self?.objectWillChange.send()
})
)
}
}
}
}
public protocol EqPublishedProtocol
{
var valueWillChange: AnyPublisher<Void, Never> { get }
}
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
@propertyWrapper public struct EqPublished<Value: Equatable>: EqPublishedProtocol
{
public var wrappedValue: Value
{
willSet
{
if wrappedValue != newValue
{
_valueWillChange.send()
}
}
didSet
{
if oldValue != wrappedValue
{
_projectedValue.send(wrappedValue)
}
}
}
public var projectedValue: AnyPublisher<Value, Never>
public var valueWillChange: AnyPublisher<Void, Never>
private var _projectedValue: CurrentValueSubject<Value, Never>
private var _valueWillChange: CurrentValueSubject<Void, Never>
/// Initialize the storage of the Published property as well as the corresponding `Publisher`.
public init(wrappedValue: Value)
{
self.wrappedValue = wrappedValue
self._projectedValue = CurrentValueSubject<Value, Never>(wrappedValue)
self.projectedValue = _projectedValue.eraseToAnyPublisher()
self._valueWillChange = CurrentValueSubject<Void, Never>()
self.valueWillChange = self._valueWillChange.eraseToAnyPublisher()
}
}
И обновленный код пользовательского интерфейса, чтобы показать его использование
HStack {
Text("ValueEq is \(model.valueEq)")
.onTapGesture {
self.count = (self.count + 1) % 3
self.model.valueEq = self.model.valueEq + (self.count == 0 ? 1 : 0)
}
.onReceive(self.model.$valueEq) { val in
print("ValueEq is \(val)")
}
Text("ValueAlways is \(model.valueAlways)")
.onTapGesture {
self.count = (self.count + 1) % 3
self.model.valueAlways = self.model.valueAlways + (self.count == 0 ? 1 : 0)
}
.onReceive(self.model.$valueAlways) { val in
print("ValueAlways is \(val)")
}
}
.onReceive(self.model.objectWillChange) { _ in
print("Object Changed")
}