命令型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
が、計算されたプロパティは使用できません。
@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
自分のクラスでa を使用する:
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
オブジェクトが変更された能力を持つことができるはずであると本質的に仮定します。それは、定義上、計算されたプロパティには当てはまりません。