Я хотел бы создать property wrapper
для CurrentValueSubject
. Я сделал это так:
@propertyWrapper
public class CurrentValue<Value> {
public var wrappedValue: Value {
get { projectedValue.value }
set { projectedValue.value = newValue }
}
public var projectedValue: CurrentValueSubject<Value, Never>
public init(wrappedValue: Value) {
self.projectedValue = CurrentValueSubject(wrappedValue)
}
}
Это работает, но есть кое-что, что я хотел бы изменить - использовать struct вместо class. Проблема с использованием struct для этого заключается в том, что иногда я могу получить Simultaneous accesses
ошибку. И я знаю, почему это происходит, когда в sink
от этого издателя я пытаюсь прочитать значение из упакованного значения. Так, например, с таким кодом:
@CurrentValue
let test = 1
$test.sink { _ in
print(self.test)
}
И я более или менее знаю, почему - потому что когда projectedValue
выполняет свое наблюдение, упакованное значение все еще находится в процессе установки его значения. В классе это нормально, потому что это просто изменило бы значение, но с помощью struct оно фактически изменяет саму структуру, поэтому я пытаюсь писать и читать из нее одновременно.
Мой вопрос - есть ли какой-нибудь умный способ преодолеть это, все еще используя struct? Я не хочу dispatch async
.
Также я знаю, что @Projected
работает аналогично этому propertyWrapper
, но есть большая разница - Projected
выполняется на willSet
, а CurrentValueSubject
на didSet
. И у Projected
такая же проблема в любом случае.
Я знаю, что могу прочитать значение внутри замыкания, но иногда я использую это с различными вызовами функций, которые могут в конечном итоге использовать self.test
.