Skip to content

Instantly share code, notes, and snippets.

@fatbobman
Last active May 11, 2022 10:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fatbobman/6bfdf92a584def7777a125ee8e2d2232 to your computer and use it in GitHub Desktop.
Save fatbobman/6bfdf92a584def7777a125ee8e2d2232 to your computer and use it in GitHub Desktop.
Similar to the @published implementation. Reference type support
@propertyWrapper
public struct PublishedObject<Value: ObservableObject> { // wrappedValue 要求符合 ObservableObject
public var wrappedValue: Value
public init(wrappedValue: Value) {
self.wrappedValue = wrappedValue
}
public static subscript<OuterSelf: ObservableObject>(
_enclosingInstance observed: OuterSelf,
wrapped wrappedKeyPath: ReferenceWritableKeyPath<OuterSelf, Value>,
storage storageKeyPath: ReferenceWritableKeyPath<OuterSelf, Self>
) -> Value where OuterSelf.ObjectWillChangePublisher == ObservableObjectPublisher {
get {
if observed[keyPath: storageKeyPath].cancellable == nil {
// 只会执行一次
observed[keyPath: storageKeyPath].setup(observed)
}
return observed[keyPath: storageKeyPath].wrappedValue
}
set {
observed.objectWillChange.send() // willSet
observed[keyPath: storageKeyPath].wrappedValue = newValue
}
}
private var cancellable: AnyCancellable?
// 订阅 wrappedvalue 的 objectWillChange
// 每当 wrappedValue 发送通知时,调用 _enclosingInstance 的 objectWillChange.send。
// 使用闭包对 _enclosingInstance 进行弱引用
private mutating func setup<OuterSelf: ObservableObject>(_ enclosingInstance: OuterSelf) where OuterSelf.ObjectWillChangePublisher == ObservableObjectPublisher {
cancellable = wrappedValue.objectWillChange.sink(receiveValue: { [weak enclosingInstance] _ in
(enclosingInstance?.objectWillChange)?.send()
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment