Myk*_*kod 16 uikit ios swift combine
所以我正在研究结合,这个问题就出现了。
使用CurrentValueSubject(并使用设置其值currentValueSubject.value)或使用 a@Published var并使用 a访问其发布者之间有什么真正的区别$吗?我的意思是我知道一个返回 aSubject而不是 a Publisher,但我能找到的唯一真正的区别是它CurrentValueSubject更有用,因为你可以在协议上声明它。
我真的不明白@Published如果我们可以使用它怎么会有用PassthroughSubject,我在这里遗漏了什么吗?
请注意,这是使用 UIKit,它可能对 SwiftUI 有其他用途。
谢谢你。
Myc*_*ner 14
CurrentValueSubject 是一个值,一个发布者和一个订阅者。
遗憾的是,它objectWillChange.send()在 ObservableObject 中使用时不会触发。
您可以指定错误类型。
@Published 是一个属性包装器,因此:
@PublishedobjectWillChange.send()在 ObservableObject 中使用时自动触发。
如果您尝试@Published从后台队列发布到包装的属性,Xcode 将发出警告。可能是因为objectWillChange.send()必须从主线程调用。
其发布者的错误类型是 Never
我最大的反对@Published是它不能作为订阅者运行,并且与当前值主题相比,设置组合管道需要额外的管道。
我们可以@Published在协议中声明一个属性。不是很漂亮...
protocol TestProtocol {
var isEnabled: Bool { get }
var isEnabledPublished: Published<Bool> { get }
var isEnabledPublisher: Published<Bool>.Publisher { get }
}
class Test: ObservableObject, TestProtocol {
@Published var isEnabled: Bool = false
var isEnabledPublished: Published<Bool> { _isEnabled }
var isEnabledPublisher: Published<Bool>.Publisher { $isEnabled }
}
Run Code Online (Sandbox Code Playgroud)
Jas*_*son 13
@Published 只是一种更简洁地使用 CurrentValueSubject 的快速方法。当我调试我的一个应用程序并查看 $paramName 返回的类型时,它实际上只是一个 CurrentValueSubject:
po self.$books
? Publisher
? subject : <CurrentValueSubject<Array<Book>, Never>: 0x6000034b8910>
Run Code Online (Sandbox Code Playgroud)
我想使用 CurrentValueSubject 而不是 @Published 的一个好处可能是允许您使用错误类型?
注意:尽管我现在是 CurrentValueSubject,但我永远不会依赖这个假设。
它的一个优点@Published是它可以充当私有可变、公共不可变的 CurrrentValueSubject。
比较:
@Published private(set) var text = "someText"
Run Code Online (Sandbox Code Playgroud)
和:
let text = CurrentValueSubject<String, Never>("someText")
Run Code Online (Sandbox Code Playgroud)
在设计 API 时,您通常希望允许客户端读取当前值并订阅更新,但阻止它们直接设置值。
我发现自己又回到了这篇文章,所以觉得我会对@Published和之间的区别添加一些额外的见解CurrentValueSubject。
可以在以下文档中找到一个主要区别@Published:
当属性更改时,发布发生在属性的 willSet 块中,这意味着订阅者在实际设置属性之前收到新值。
此外,Swift 论坛上的对话说明@Published旨在与 SwiftUI 一起使用。
关于@Published在willSet其属性的块中发布,请考虑以下示例:
class PublishedModel {
@Published var number: Int = 0
}
let pModel = PublishedModel()
pModel.$number.sink { number in
print("Closure: \(number)")
print("Object: \(pModel.number) [read via closure]")
}
pModel.number = 1
print("Object: \(pModel.number) [read after assignment]")
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
Closure: 0
Object: 0 [read via closure]
Closure: 1
Object: 0 [read via closure]
Object: 1 [read after assignment]
Run Code Online (Sandbox Code Playgroud)
将此与另一个我们保持所有内容相同的示例进行对比,除了替换@Published为CurrentValueSubject:
class CurrentValueSubjectModel {
var number: CurrentValueSubject<Int, Never> = .init(0)
}
let cvsModel = CurrentValueSubjectModel()
cvsModel.number.sink { number in
print("Closure: \(number)")
print("Object: \(cvsModel.number.value) [read via closure]")
}
cvsModel.number.send(1)
print("Object: \(cvsModel.number.value) [read after assignment]")
Run Code Online (Sandbox Code Playgroud)
输出:
Closure: 0
Object: 0 [read via closure]
Closure: 1
Object: 1 [read via closure] // <— Here is the difference
Object: 1 [read after assignment]
Run Code Online (Sandbox Code Playgroud)
更新后number至1,阅读对象CurrentValueSubject的价值属性中关闭打印新值代替旧值与@Published。
总之,@Published在您ObservableObjects的 SwiftUI 视图中使用。如果您希望创建某种模型对象,其实例属性保存当前值并在设置后发布更改,请使用CurrentValueSubject.
| 归档时间: |
|
| 查看次数: |
4834 次 |
| 最近记录: |