En el imperativo Swift, es común usar propiedades calculadas para proporcionar un acceso conveniente a los datos sin duplicar el estado.
Digamos que tengo esta clase hecha para uso MVC imperativo:
class ImperativeUserManager {
private(set) var currentUser: User? {
didSet {
if oldValue != currentUser {
NotificationCenter.default.post(name: NSNotification.Name("userStateDidChange"), object: nil)
// Observers that receive this notification might then check either currentUser or userIsLoggedIn for the latest state
}
}
}
var userIsLoggedIn: Bool {
currentUser != nil
}
// ...
}
Si quiero crear un equivalente reactivo con Combine, por ejemplo, para usar con SwiftUI, puedo agregar fácilmente @Publisheda las propiedades almacenadas para generar Publishers, pero no para las propiedades calculadas.
@Published var userIsLoggedIn: Bool { // Error: Property wrapper cannot be applied to a computed property
currentUser != nil
}
Hay varias soluciones que se me ocurren. Podría hacer que mi propiedad calculada se almacene en su lugar y mantenerla actualizada.
Opción 1: Usar un observador de propiedades:
class ReactiveUserManager1: ObservableObject {
@Published private(set) var currentUser: User? {
didSet {
userIsLoggedIn = currentUser != nil
}
}
@Published private(set) var userIsLoggedIn: Bool = false
// ...
}
Opción 2: Usar a Subscriberen mi propia clase:
class ReactiveUserManager2: ObservableObject {
@Published private(set) var currentUser: User?
@Published private(set) var userIsLoggedIn: Bool = false
private var subscribers = Set<AnyCancellable>()
init() {
$currentUser
.map { $0 != nil }
.assign(to: \.userIsLoggedIn, on: self)
.store(in: &subscribers)
}
// ...
}
Sin embargo, estas soluciones alternativas no son tan elegantes como las propiedades calculadas. Duplican el estado y no actualizan ambas propiedades simultáneamente.
¿Cuál sería un equivalente apropiado para agregar Publishera una propiedad calculada en Combine?

ObservableObject. Inherentemente asume que unObservableObjectobjeto debería tener una capacidad de mutación que, por definición, no es el caso de la propiedad calculada .Respuestas:
¿Qué tal el uso aguas abajo?
De esta manera, la suscripción obtendrá un elemento de upstream, luego puede usar
sinkoassignhacer ladidSetidea.fuente
Cree un nuevo editor suscrito a la propiedad que desea rastrear.
Entonces podrá observarlo como si fuera su
@Publishedpropiedad.No está directamente relacionado pero es útil, sin embargo, puede rastrear múltiples propiedades de esa manera
combineLatest.fuente
Debes declarar un PassthroughSubject en tu ObservableObject:
Y en el didSet (willSet podría ser mejor) de su var @Published usará un método llamado send ()
Puede verificarlo en la charla de flujo de datos WWDC
fuente
@Publishedwrapper yPassthroughSubjectambos sirven el mismo propósito en este contexto. Presta atención a lo que escribiste y a lo que el OP realmente quería lograr. ¿Su solución sirve como la mejor alternativa que la opción 1 en realidad?scan ( : :) Transforma elementos del publicador ascendente al proporcionar el elemento actual a un cierre junto con el último valor devuelto por el cierre.
Puede usar scan () para obtener el valor más reciente y actual. Ejemplo:
El código anterior es equivalente a esto: (menos Combinar)
fuente