3
Swift 中的 ObservableObject
source link: https://kingcos.me/posts/2022/swift_observable_object/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Release Notes
↕
Preface
ObservableObject
相比 @State
更自由一些。仅 class
类型可以遵守该协议。视图使用时可以声明为 @ObservedObject
,也可使用 @EnvironmentObject
注入。
先来看下 ObservableObject
的部分代码:
/// A type of object with a publisher that emits before the object has changed.
/// 一种带有发布者的对象类型,其在对象更改之前发出。
///
/// By default an ``ObservableObject`` synthesizes an ``ObservableObject/objectWillChange-2oa5v`` publisher that emits the changed value before any of its `@Published` properties changes.
/// 默认情况下,``ObservableObject`` 合成一个 ``ObservableObject/objectWillChange-2oa5v`` 发布者,其在任何 `Published` 属性更改之前发出更改的值。
///
/// class Contact: ObservableObject {
/// @Published var name: String
/// @Published var age: Int
///
/// init(name: String, age: Int) {
/// self.name = name
/// self.age = age
/// }
///
/// func haveBirthday() -> Int {
/// age += 1
/// return age
/// }
/// }
///
/// let john = Contact(name: "John Appleseed", age: 24)
/// cancellable = john.objectWillChange
/// .sink { _ in
/// print("\(john.age) will change")
/// }
/// print(john.haveBirthday())
/// // Prints "24 will change"
/// // Prints "25"
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
public protocol ObservableObject : AnyObject {
/// The type of publisher that emits before the object has changed.
associatedtype ObjectWillChangePublisher : Publisher = ObservableObjectPublisher where Self.ObjectWillChangePublisher.Failure == Never
/// A publisher that emits before the object has changed.
var objectWillChange: Self.ObjectWillChangePublisher { get }
}
以其中代码为例:
class Contact: ObservableObject {
@Published var name: String
@Published var age: Int // 2. -> objectWillChange
init(name: String, age: Int) {
self.name = name
self.age = age
}
func haveBirthday() -> Int {
age += 1 // 1. 改变 age
return age
}
}
let john = Contact(name: "John Appleseed", age: 24)
let cancellable = john.objectWillChange
.sink { _ in
print("\(john.age) will change") // 3. 输出
}
print(john.haveBirthday()) // 4. 打印结果
// Prints "24 will change"
// Prints "25"
而 @Published
的本质是通过 willSet
和 objectWillChange
实现的,也可使用以下方式:
class Contact: ObservableObject {
let objectWillChange = PassthroughSubject<Void, Never>()
var age = 0 {
// 手动在将要设置时调用 send
willSet { // 2.1 willSet 调用
print("age - objectWillChange.send")
// 2.1.1 手动调用 objectWillChange.send
objectWillChange.send()
}
}
var name = "" {
willSet { // 2.2 willSet 调用
print("name - objectWillChange.send")
// 2.2.1 手动调用 objectWillChange.send
objectWillChange.send()
}
}
init(name: String, age: Int) {
self.name = name
self.age = age
}
func haveBirthday() -> Int {
age += 1 // 1. 改变 age
return age
}
}
let john = Contact(name: "John Appleseed", age: 24)
let cancellable = john.objectWillChange
.sink { _ in
print("\(john.age) will change") // 3. 输出
}
print(john.haveBirthday()) // 4. 打印结果
// age - objectWillChange.send
// 24 will change
// 25
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK