W trybie imperatywnym Szybki często stosuje się właściwości obliczeniowe, aby zapewnić wygodny dostęp do danych bez powielania stanu.
Powiedzmy, że mam tę klasę do bezwzględnego użycia 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
}
// ...
}
Jeśli chcę utworzyć reaktywny ekwiwalent za pomocą Łączenia, np. Do użytku ze SwiftUI, mogę łatwo dodać @Published
do przechowywanych właściwości w celu wygenerowania Publisher
s, ale nie dla właściwości obliczonych.
@Published var userIsLoggedIn: Bool { // Error: Property wrapper cannot be applied to a computed property
currentUser != nil
}
Istnieją różne obejścia, o których mógłbym pomyśleć. Mógłbym zamiast tego zapisać moją właściwość obliczoną i aktualizować ją.
Opcja 1: Korzystanie z obserwatora właściwości:
class ReactiveUserManager1: ObservableObject {
@Published private(set) var currentUser: User? {
didSet {
userIsLoggedIn = currentUser != nil
}
}
@Published private(set) var userIsLoggedIn: Bool = false
// ...
}
Opcja 2: Korzystanie z Subscriber
własnej klasy:
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)
}
// ...
}
Jednak te obejścia nie są tak eleganckie, jak obliczone właściwości. Powielają stan i nie aktualizują obu właściwości jednocześnie.
Jaki byłby odpowiedni odpowiednik dodania Publisher
do obliczonej właściwości w Combine?
ObservableObject
. Zakładasz z natury, że ObservableObject
obiekt powinien mieć zdolność mutowania, co z definicji nie ma miejsca w przypadku właściwości obliczonej .