Swift中如何不使用debugDescription获取Published<String>的值?
解决@Published变量的下标访问与值获取问题
核心改进方案
- 抛弃解析
debugDescription的不可靠方式,直接利用Published作为@propertyWrapper的标准API——wrappedValue属性获取实际值 - 优化下标逻辑,支持直接传入原始属性名(如
"str"),无需手动拼接编译器生成的下划线前缀("_str")
修改后的完整代码
import Foundation import Combine protocol PropertyReflectable {} extension PropertyReflectable { subscript(key: String) -> Any? { // 优先查找非@Published属性 if let value = Mirror(reflecting: self).children.first({ $0.label == key })?.value { return value } // 自动拼接下划线前缀,查找@Published生成的存储属性 let publishedKey = "_\(key)" return Mirror(reflecting: self).children.first({ $0.label == publishedKey })?.value } } class Foo : PropertyReflectable { @Published var str: String = "bar" var str2: String = "bar2" } // 直接通过wrappedValue获取Published包装的实际值 func getStringValue(_ obj: Combine.Published<String>?) -> String? { return obj?.wrappedValue } let f = Foo() // 现在可以直接用原始属性名"str"访问 let str = getStringValue(f["str"] as? Published<String>) print("got str: \(str!)") // 输出: got str: bar let str2 = f["str2"] as! String print("got non-published string easily: \(str2)") // 输出: got non-published string easily: bar2
细节说明
wrappedValue的可靠性:@Published是官方定义的@propertyWrapper,所有符合规范的包装器都会公开wrappedValue属性来暴露被包装的实际值,这是官方支持的稳定访问方式,完全不会受debugDescription格式变更的影响。下标逻辑优化:原代码需要手动传入下划线前缀的属性名,修改后的下标会先尝试原始属性名,失败后自动拼接下划线查找编译器生成的
@Published存储属性,使用时更符合直觉。类型安全升级(可选):如果需要更严格的类型安全,可以添加泛型版本的下标,避免频繁类型转换:
extension PropertyReflectable { subscript<T>(key: String) -> T? { // 直接获取非@Published属性 if let value = Mirror(reflecting: self).children.first({ $0.label == key })?.value as? T { return value } // 获取@Published属性并自动解包wrappedValue let publishedKey = "_\(key)" if let publishedValue = Mirror(reflecting: self).children.first({ $0.label == publishedKey })?.value as? Published<T> { return publishedValue.wrappedValue } return nil } }
使用泛型下标时无需额外的getStringValue函数:
let str = f["str"] as String? print("got str: \(str!)") let str2 = f["str2"] as String? print("got non-published string easily: \(str2!)")
内容的提问来源于stack exchange,提问作者Kem Mason
相关产品推荐
相关产品推荐

