【问题标题】:SwiftUI ObservableObject used as EnvironmentObject odd behaviourSwiftUI ObservableObject 用作​​ EnvironmentObject 奇怪的行为
【发布时间】:2019-11-26 09:15:30
【问题描述】:

我有这样的ObservableObject,我通过使用environmentObject() 将其注入到视图层次结构中。

class MenuModel: ObservableObject {

    @Published var selection: Int = 0
    @Published var isMenuOpen: Bool = false

    @Published var tabItems : [TabItem] = [TabItem]()
//    {
//        didSet {
//            objectWillChange.send()
//        }
//    }
    @Published var menuItems : [MenuItem] = [MenuItem]()
//    {
//        didSet {
//            objectWillChange.send()
//        }
//    }

    //var objectWillChange = PassthroughSubject<Void, Never>()
}

以下是我不太了解的问题: 1.上面的代码可以正常工作,因为所有属性都是@Published。 2. 但是如果我把它改成这样的

class Click5MenuModel: ObservableObject {

    @Published var selection: Int = 0
    @Published var isMenuOpen: Bool = false

    var tabItems : [TabItem] = [TabItem]()
    {
        didSet {
            objectWillChange.send()
        }
    }
    var menuItems : [MenuItem] = [MenuItem]()
    {
        didSet {
            objectWillChange.send()
        }
    }

    var objectWillChange = PassthroughSubject<Void, Never>()
}

然后@Published 属性停止刷新依赖于这个 ObservableObject 的视图! 这是为什么。我还尝试将didSetobjectWillChange.send() 添加,但这也会导致一些奇怪的行为并且代码有点尴尬。

这是否意味着我只能使用 ONLY @PublishedONLY objectWillChange 方法?

【问题讨论】:

  • 您只想知道原因或如何使其发挥作用吗?因为通过我的测试删除了您本地定义的objectWillChange 并使用从ObservableObject 继承的didSet,即。 didSet { self.objectWillChange.send() } 按预期更新视图。以防万一。
  • objectWillChange 是我本地定义的吗?所以我根本不应该放置它?我添加了这个,因为大多数示例都使用它,但正如你所说,我应该只在 didSet 中调用它?

标签: swiftui combine observableobject


【解决方案1】:

默认实现可以正常工作(只要你有 @Published 属性)。以下是 API 声明:

/// By default an `ObservableObject` will synthesize an `objectWillChange`
/// publisher that emits before any of its `@Published` properties changes:
...
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
extension ObservableObject where Self.ObjectWillChangePublisher == ObservableObjectPublisher {

    /// A publisher that emits before the object has changed.
    public var objectWillChange: ObservableObjectPublisher { get }
}

所以删除以下内容:

var objectWillChange = PassthroughSubject<Void, Never>()

并使用

didSet {
    self.objectWillChange.send()
}

【讨论】:

  • 我认为在使用didSet 而不是willSet 调用objectWillChange 时,您必须期待奇怪的行为(u)r。有用的讨论在这里:pointfree.co/blog/posts/…
猜你喜欢
  • 1970-01-01
  • 2021-05-07
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
  • 1970-01-01
  • 2022-01-07
相关资源
最近更新 更多