В императивном 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
к вычисляемому свойству в Combine?
ObservableObject
. Вы по своей сути считать , что ObservableObject
объект должен иметь возможность иметь мутирует способность , которая, по определению, не является случаем для компьютерной собственности .