gpt4 book ai didi

swift - 是否可以在 Swift 中的结构变量上添加一个观察者?

转载 作者:搜寻专家 更新时间:2023-11-01 05:49:21 24 4
gpt4 key购买 nike

我需要在结构类型的变量中跟踪更新。是否可以在 Swift 中对结构变量添加观察者?

例子:

struct MyCustomStruct {
var error:Error?
var someVar:String?
}

class MyClass{
var myCustomStruct:MyCustomStruct?
}

我想在 myCustomStruct 变量上添加一个观察者。

最佳答案

标准的 Swift “property observers ” (didSetwillSet) 旨在让类型观察其自身属性的变化,而不是让外部对象添加自己的观察者。而支持外部观察者的 KVO 仅适用于 dynamic@objc 属性 NSObject 子类(如 Using Key-Value Observing in Swift 中所述)。

因此,如果你想让外部对象观察 struct 中的变化,正如其他人指出的那样,你必须使用 Swift didSet 创建你自己的观察者机制之类的。但是,与其自己一个属性一个属性地实现它,您还可以编写一个泛型类型来为您完成这项工作。例如,

struct Observable<T> {
typealias Observer = String

private var handlers: [Observer: (T) -> Void] = [:]

var value: T {
didSet {
handlers.forEach { $0.value(value) }
}
}

init(_ value: T) {
self.value = value
}

@discardableResult
mutating func observeNext(_ handler: @escaping (T) -> Void) -> Observer {
let key = UUID().uuidString as Observer
handlers[key] = handler
return key
}

mutating func remove(_ key: Observer) {
handlers.removeValue(forKey: key)
}
}

然后你可以这样做:

struct Foo {
var i: Observable<Int>
var text: Observable<String>

init(i: Int, text: String) {
self.i = Observable(i)
self.text = Observable(text)
}
}

class MyClass {
var foo: Foo

init() {
foo = Foo(i: 0, text: "foo")
}
}

let object = MyClass()
object.foo.i.observeNext { [weak self] value in // the weak reference is really only needed if you reference self, but if you do, make sure to make it weak to avoid strong reference cycle
print("new value", value)
}

然后,当您更新属性时,例如如下所示,您的观察者处理程序闭包将被调用:

object.foo.i.value = 42

值得注意的是像 Bond 这样的框架或 RxSwift提供这种功能,还有更多。

关于swift - 是否可以在 Swift 中的结构变量上添加一个观察者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54231759/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com