我有以下代码:
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 )
}
}但是当我执行的时候:
let doSomething = DoSomething()
doSomething.observedObject.stuff?.str = "Doing something"
doSomething.observedObject.stuff?.num = 2,通知永远不会触发:

你们知道为什么通知永远不会触发吗?或者我怎样才能做到这一点?
发布于 2021-10-20 06:30:23
正如在注释中所建议的,如果你想让它工作,你需要将你的类转换成一个结构:struct Stuff {。结构是一种值类型,这使得它可以很好地与ObservableObject一起工作,而类是一种引用类型,它并不能很好地工作。
@Published属性需要是“纯”值类型,如果您希望在其内容中的某些内容发生更改时得到通知。我所说的“纯”是指仅由其他值类型组成的值类型,这些值类型也是“纯”的。
为什么需要这样做?这是因为@Published机制依赖于willSet/didSet属性观察器,而属性观察器只有在它们持有的值发生变化时才会执行。
对于值类型,其结构中的任何更改都会向上传播,从而导致整个属性被更新。这是由于值类型的语义造成的。
请看下面的代码片段:
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观察者。试试这个,你会看到通知被触发了:
doSomething.observedObject.stuff = Stuff() // this will print `Object has changed`发布于 2021-10-19 16:31:06
问题出在doSomething.observedObject.stuff,它是空的。
我修复了:
let doSomething = DoSomething()
let stuff = Stuff()
stuff.str = "Doig Something"
doSomething.observedObject.stuff = stuffhttps://stackoverflow.com/questions/69634368
复制相似问题