@Published需要willSet触发

时间:2020-06-16 20:33:59

标签: swift swiftui

我有一堂课:

/

然后我有一个观察此类的视图:

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} }的实现,但这似乎没有发生。相反,我必须手动调用更新。为什么呢?

2 个答案:

答案 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>()