В імперативі Swift звичайно використовувати обчислювані властивості для забезпечення зручного доступу до даних без дублювання стану.
Скажімо, у мене цей клас зроблений для обов'язкового використання 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
}
// ...
}
Якщо я хочу створити реактивний еквівалент із Combine, наприклад для використання з SwiftUI, я можу легко додати @Published
до збережених властивостей для створення Publisher
s, але не для обчислених властивостей.
@Published var userIsLoggedIn: Bool { // Error: Property wrapper cannot be applied to a computed property
currentUser != nil
}
Є різні шляхи вирішення, які я міг би придумати. Я міг би зробити моє обчислене властивість збереженим замість цього і постійно оновлювати його.
Варіант 1: Використання спостерігача властивості:
class ReactiveUserManager1: ObservableObject {
@Published private(set) var currentUser: User? {
didSet {
userIsLoggedIn = currentUser != nil
}
}
@Published private(set) var userIsLoggedIn: Bool = false
// ...
}
Варіант 2: Використання Subscriber
в моєму власному класі:
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)
}
// ...
}
Однак ці способи вирішення не такі елегантні, як обчислювальні властивості. Вони дублюють стан, і вони не оновлюють обидва властивості одночасно.
Що було б відповідним еквівалентом додаванню Publisher
до обчислюваної властивості в "Комбінат"?
ObservableObject
. Ви за своєю суттю припускаєте, що ObservableObject
об’єкт повинен мати здатність мутувати, що, за визначенням, не має відношення до обчислюваної властивості .