You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Combine框架中KVO Publisher属性变更时未发送信号的问题咨询

问题分析与修复方案

你遇到的问题其实是Combine KVO Publisher的常见坑——Swift属性默认不支持KVO的动态监听,除非你明确告诉编译器要为它启用运行时的动态派发支持。

问题根源

你的SampleClass里的name属性只加了@objc,但缺少dynamic修饰符。Combine的KVO Publisher底层依赖Objective-C的KVO机制,而KVO要求属性的setter方法能被运行时动态替换(isa-swizzling),Swift的@objc属性默认是静态派发的,所以当你修改a.name时,并不会触发KVO通知,自然Combine的Publisher也就不会发送新值事件。

修复代码

只需要给name属性加上dynamic修饰即可:

@objc class SampleClass: NSObject { 
    @objc dynamic var name: NSString = "1" // 这里加上dynamic
}
var a = SampleClass()
let kvoPublisher = a.publisher(for: \.name)
    .sink(receiveCompletion: { print("completion \($0)") }, 
          receiveValue: { newVal in print("new val - \(newVal)") })
a.name = "2"
a.name = "3"
print("Finished; publisher = \(kvoPublisher) | a.name = \(a.name)")

修复后的输出

运行修改后的代码,控制台会输出:

new val - 1
new val - 2
new val - 3
Finished; publisher = Combine.AnyCancellable | a.name = 3

额外注意点

另外提一句:你的kvoPublisher(AnyCancellable)被赋值给了顶层变量,这保证了它不会被提前释放,所以能持续接收事件。如果是在函数内部创建的AnyCancellable,记得要把它存入一个Set<AnyCancellable>或者保持引用,否则会被销毁,导致Publisher停止工作。

内容的提问来源于stack exchange,提问作者nrx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 01:52:46