获取可以更新值的 @Published 的引用
Get reference for an @Published that can update the value
我正在尝试动态更新对 @Published var
的引用,但我不确定该怎么做。仅返回值只是一个 bool 值,并且会丢失它对发布者的引用并且不起作用。我尝试返回发布者本身 ($self.isBig
) 但我似乎无法弄清楚一旦拥有发布者而不是 @Published 属性.
如何更新值
我基本上只是尝试将 @Published
视为参考并更新 class 上的参考,而不是复制发布者的值。
这是一个人为的例子,只是为了说明问题,我想做的是:
import UIKit
import Combine
class MyClass {
struct MyData {
enum MyDataType {
case big
case yellow
case bird
}
var type: MyDataType
var isEnabled: Bool
}
private var cancellables = Set<AnyCancellable>()
@Published var isBig: Bool = false
@Published var isYellow: Bool = false
@Published var isBird: Bool = false
var mySwitch = UISwitch()
init() {
// Add mySwitch and setupSubscribers...
}
func updatePublishers(from data: MyData) {
let publisherForData = specificPublisherForData(data)
// I want to access the underlying value for the @Published and set it here
// publisherForData = data.isEnabled
}
func specificPublisherForData(_ data: MyData) -> Published<Bool>.Publisher {
switch data.type {
case .big: return self.$isBig
case .yellow: return self.$isYellow
case .bird: return self.$isBird
}
}
func setupSubscribers() {
$isBig.sink { [weak self] isBig in
guard let self = self else { return }
self.mySwitch.isOn = isBig
}.store(in: &cancellables)
// ... add subscribers for the other ones
}
}
您似乎在尝试为 updatePublishers
中的 Publisher
分配一个 新值,但实际上并非如此 @Publisher
的工作——他们只是在传播价值观。
相反,您可能需要使用关键路径:
class MyClass {
struct MyData {
enum MyDataType {
case big
case yellow
case bird
}
var type: MyDataType
var isEnabled: Bool
}
private var cancellables = Set<AnyCancellable>()
@Published var isBig: Bool = false
@Published var isYellow: Bool = false
@Published var isBird: Bool = false
var mySwitch = UISwitch()
init() {
// Add mySwitch and setupSubscribers...
}
func updatePublishers(from data: MyData) {
let keypath = specificKeypathForData(data)
self[keyPath: keypath] = data.isEnabled
}
func specificKeypathForData(_ data: MyData) -> ReferenceWritableKeyPath<MyClass,Bool> {
switch data.type {
case .big: return \.isBig
case .yellow: return \.isYellow
case .bird: return \.isBird
}
}
func setupSubscribers() {
$isBig.sink { [weak self] isBig in
guard let self = self else { return }
self.mySwitch.isOn = isBig
}.store(in: &cancellables)
// ... add subscribers for the other ones
}
}
在操场上:
var myClass = MyClass()
myClass.setupSubscribers()
var data = MyClass.MyData(type: .big, isEnabled: true)
myClass.updatePublishers(from: data)
print(myClass.isBig)
产量:
true
我正在尝试动态更新对 @Published var
的引用,但我不确定该怎么做。仅返回值只是一个 bool 值,并且会丢失它对发布者的引用并且不起作用。我尝试返回发布者本身 ($self.isBig
) 但我似乎无法弄清楚一旦拥有发布者而不是 @Published 属性.
我基本上只是尝试将 @Published
视为参考并更新 class 上的参考,而不是复制发布者的值。
这是一个人为的例子,只是为了说明问题,我想做的是:
import UIKit
import Combine
class MyClass {
struct MyData {
enum MyDataType {
case big
case yellow
case bird
}
var type: MyDataType
var isEnabled: Bool
}
private var cancellables = Set<AnyCancellable>()
@Published var isBig: Bool = false
@Published var isYellow: Bool = false
@Published var isBird: Bool = false
var mySwitch = UISwitch()
init() {
// Add mySwitch and setupSubscribers...
}
func updatePublishers(from data: MyData) {
let publisherForData = specificPublisherForData(data)
// I want to access the underlying value for the @Published and set it here
// publisherForData = data.isEnabled
}
func specificPublisherForData(_ data: MyData) -> Published<Bool>.Publisher {
switch data.type {
case .big: return self.$isBig
case .yellow: return self.$isYellow
case .bird: return self.$isBird
}
}
func setupSubscribers() {
$isBig.sink { [weak self] isBig in
guard let self = self else { return }
self.mySwitch.isOn = isBig
}.store(in: &cancellables)
// ... add subscribers for the other ones
}
}
您似乎在尝试为 updatePublishers
中的 Publisher
分配一个 新值,但实际上并非如此 @Publisher
的工作——他们只是在传播价值观。
相反,您可能需要使用关键路径:
class MyClass {
struct MyData {
enum MyDataType {
case big
case yellow
case bird
}
var type: MyDataType
var isEnabled: Bool
}
private var cancellables = Set<AnyCancellable>()
@Published var isBig: Bool = false
@Published var isYellow: Bool = false
@Published var isBird: Bool = false
var mySwitch = UISwitch()
init() {
// Add mySwitch and setupSubscribers...
}
func updatePublishers(from data: MyData) {
let keypath = specificKeypathForData(data)
self[keyPath: keypath] = data.isEnabled
}
func specificKeypathForData(_ data: MyData) -> ReferenceWritableKeyPath<MyClass,Bool> {
switch data.type {
case .big: return \.isBig
case .yellow: return \.isYellow
case .bird: return \.isBird
}
}
func setupSubscribers() {
$isBig.sink { [weak self] isBig in
guard let self = self else { return }
self.mySwitch.isOn = isBig
}.store(in: &cancellables)
// ... add subscribers for the other ones
}
}
在操场上:
var myClass = MyClass()
myClass.setupSubscribers()
var data = MyClass.MyData(type: .big, isEnabled: true)
myClass.updatePublishers(from: data)
print(myClass.isBig)
产量:
true