我有一堂课:
/
然后我有一个观察此类的视图:
final class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
let objectWillChange = PassthroughSubject<Void, Never>()
private let locationManager = CLLocationManager()
@Published var status: String? {
willSet { objectWillChange.send() }
}
@Published var location: CLLocation? {
willSet { objectWillChange.send() }
}
// ...other code
}
一切正常,发布属性更改时,视图也会更新。但是,如果删除struct MapView: UIViewRepresentable {
@ObservedObject var lm = LocationManager()
// ...other view code
}
,则发布位置更改时,观察willSet { objectWillChange.send() }
实例的视图不会更新。这使我想到了一个问题:我认为,通过将LocationManager
放在@Published
旁边,当发布的属性发生更改时,任何var
都会使当前视图无效,实质上是默认的{{1} }的实现,但这似乎没有发生。相反,我必须手动调用更新。为什么呢?
答案 0 :(得分:3)
您正在做太多工作。看来您正在尝试 write ObservableObject。您不需要它已经存在。关键是ObservableObject是 readable 可自动观察的。这是一个非Swift的示例:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
do_stuff_forever();
}
public void do_stuff_forever() {
while (1 < 2) { Debug.WriteLine(" lol "); }
}
}
需要注意的是,尽管可观察对象根本不包含任何代码,但每次设置其final class Thing: NSObject, ObservableObject {
@Published var status: String?
}
class ViewController: UIViewController {
var storage = Set<AnyCancellable>()
let thing = Thing()
override func viewDidLoad() {
self.thing.objectWillChange
.sink {_ in print("will change")}.store(in: &self.storage)
self.thing.$status
.sink { print($0) }.store(in: &self.storage)
}
@IBAction func doButton (_ sender:Any) {
self.thing.status = (self.thing.status ?? "") + "x"
}
}
属性时,它都会发出一个信号,即该属性发生变化之前。然后status
属性本身发出一个信号,即它的新值。
在SwiftUI中也会发生同样的事情。
答案 1 :(得分:1)
Apple文档指出:
默认情况下,ObservableObject会合成一个对象WillChange 在任何@Published之前发出更改后的值的发布者 属性发生变化。
这意味着您无需声明自己的objectWillChange
。您只需从代码中删除objectWillChange
,包括以下行:
let objectWillChange = PassthroughSubject<Void, Never>()