ในความจำเป็นอย่างรวดเร็วมันเป็นเรื่องธรรมดาที่จะใช้คุณสมบัติคำนวณเพื่อให้เข้าถึงข้อมูลได้สะดวกโดยไม่ต้องทำซ้ำ
สมมติว่าฉันมีคลาสนี้ทำขึ้นสำหรับการใช้ 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
}
// ...
}
ถ้าฉันต้องการสร้างรีแอคทีฟที่เทียบเท่ากับการรวมเช่นสำหรับใช้กับ 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
วัตถุควรมีความสามารถในการกลายพันธุ์ซึ่งตามนิยามแล้วจะไม่เกิดขึ้นกับคุณสมบัติที่คำนวณได้