In imperativo Swift, è comune utilizzare proprietà calcolate per fornire un comodo accesso ai dati senza duplicare lo stato.
Diciamo che ho creato questa classe per l'uso imperativo di MVC:
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
}
// ...
}
Se voglio creare un equivalente reattivo con Combine, ad esempio per l'uso con SwiftUI, posso facilmente aggiungere @Published
proprietà memorizzate per generare messaggi Publisher
, ma non per proprietà calcolate.
@Published var userIsLoggedIn: Bool { // Error: Property wrapper cannot be applied to a computed property
currentUser != nil
}
Ci sono varie soluzioni alternative che mi vengono in mente. Potrei invece archiviare la mia proprietà calcolata e mantenerla aggiornata.
Opzione 1: utilizzo di un osservatore proprietà:
class ReactiveUserManager1: ObservableObject {
@Published private(set) var currentUser: User? {
didSet {
userIsLoggedIn = currentUser != nil
}
}
@Published private(set) var userIsLoggedIn: Bool = false
// ...
}
Opzione 2: utilizzo di a Subscriber
nella mia classe:
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)
}
// ...
}
Tuttavia, queste soluzioni alternative non sono eleganti come le proprietà calcolate. Duplicano lo stato e non aggiornano entrambe le proprietà contemporaneamente.
Quale sarebbe un vero e proprio equivalente all'aggiunta di una Publisher
a una proprietà calcolata in Combina?
ObservableObject
. Supponi intrinsecamente che un ObservableObject
oggetto dovrebbe essere in grado di avere un'abilità mutante che, per definizione, non è il caso della proprietà calcolata .