swift 快速合并:'sink'可以和model.$name一起使用,但不能和model. name. publisher一起使用,为什么?

lvmkulzt  于 2022-12-10  发布在  Swift
关注(0)|答案(2)|浏览(154)

我有一个带有发布名称属性的模型:

@MainActor class MyModel:ObservableObject {
    
    @Published private(set) var name = ""

    ....

}

我想知道为什么sink在model.$name上使用时可以工作,而在model.name.publisher上不可以。

model.$name
    .receive(on: RunLoop.main)
    .sink { name in
        ....            <-- it's called. works.
    }
    .store(in: &subs)

这不会被称为:

model.name.publisher
    .receive(on: RunLoop.main)
    .sink { name in
        ....            <-- does not get called.
    }
    .store(in: &subs)

有人能解释一下为什么我必须在name前面使用$符号,为什么name.publisher不起作用吗?

yhived7q

yhived7q1#

$name是您存取@Published属性 Package 函数之基础Publisher的方式。每次name属性变异时,这个出版者都会发出,而这可能正是您想要的。
使用model.name.publisher,您会得到一个Publisher,它将发出String的每个字符,然后完成(它在Sequence扩展上定义)如果您有:

@MainActor class MyModel:ObservableObject {
    
    @Published private(set) var name = "foo"

    ....

}

您将看到f - o - o

ryevplcw

ryevplcw2#

在这个特殊的情况下,我明白为什么它的困惑。
$name引用@Published属性 Package 中的发布者。这就是您所需要的。
name.publisher是String中的一个元素。Fabio Felici的答案很好地解释了它。它将循环遍历当前字符串的字符(返回String.Element),而不是在换出字符串时的新值。为此,使用$name。(在sink上,每次更改都返回一个String类型。)

相关问题