首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更改ObservedObject时未发送通知

更改ObservedObject时未发送通知
EN

Stack Overflow用户
提问于 2021-10-19 16:14:21
回答 2查看 61关注 0票数 0

我有以下代码:

代码语言:javascript
复制
class Stuff {
    var str: String?
    var num = 0
}

class MyStuff:ObservableObject {
    @Published var stuff:Stuff?
    @Published var numer: Int?
}

class DoSomething {
    let observedObject = MyStuff()
    var cancellableBag = Set<AnyCancellable>()
    
    init() {
        observedObject.objectWillChange.sink { value in
            print(value)
            print("Object has changed")
        }.store(in: &cancellableBag)
        observedObject.$stuff.sink { value in
            print(value?.str ?? "")
        }.store(in: &cancellableBag )
    }
}

但是当我执行的时候:

代码语言:javascript
复制
let doSomething = DoSomething()
doSomething.observedObject.stuff?.str = "Doing something"
doSomething.observedObject.stuff?.num = 2

,通知永远不会触发:

你们知道为什么通知永远不会触发吗?或者我怎样才能做到这一点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-20 06:30:23

正如在注释中所建议的,如果你想让它工作,你需要将你的类转换成一个结构:struct Stuff {。结构是一种值类型,这使得它可以很好地与ObservableObject一起工作,而类是一种引用类型,它并不能很好地工作。

@Published属性需要是“纯”值类型,如果您希望在其内容中的某些内容发生更改时得到通知。我所说的“纯”是指仅由其他值类型组成的值类型,这些值类型也是“纯”的。

为什么需要这样做?这是因为@Published机制依赖于willSet/didSet属性观察器,而属性观察器只有在它们持有的值发生变化时才会执行。

对于值类型,其结构中的任何更改都会向上传播,从而导致整个属性被更新。这是由于值类型的语义造成的。

请看下面的代码片段:

代码语言:javascript
复制
struct Question {
    var title: String = ""
}

class Page {
    var question = Question() {
        didSet {
            print("Question changed: \(question)")
        }
    }
}

let page = Page()
page.question.title = "@Published doesn't work"

question成员的任何更改都会导致整个属性被替换,这会触发willSet/didSet属性观察器,因此您可以很好地监视question数据结构中的任何更改。

然而,对于类来说,上述情况并非如此。类有标识,它们有固定的内存位置,与值类型不同,值类型在使用时会被复制得到处都是。这意味着它们内部结构中的更改不会反映在上游,因为类实例存储不会更改。

只有当您替换对象本身时,才会为类触发@Published观察者。试试这个,你会看到通知被触发了:

代码语言:javascript
复制
doSomething.observedObject.stuff = Stuff() // this will print `Object has changed`
票数 1
EN

Stack Overflow用户

发布于 2021-10-19 16:31:06

问题出在doSomething.observedObject.stuff,它是空的。

我修复了:

代码语言:javascript
复制
let doSomething = DoSomething()
let stuff = Stuff()
stuff.str = "Doig Something"
doSomething.observedObject.stuff = stuff
票数 -4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69634368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档