自定义UserDefaults套件的Swift Publisher无法正常更新订阅
自定义UserDefaults套件下订阅无法触发更新的问题
当使用自定义套件的UserDefaults时,通过publisher(for:)创建的订阅只能获取初始值,后续修改值时无法触发订阅回调。但SwiftUI视图中的onReceive订阅却能正常响应值的变化。如果切换回默认的standard UserDefaults套件,所有订阅(包括直接创建的sink订阅)都能正常触发(即使存在重复调用的情况)。
自定义套件的代码示例
public extension UserDefaults { @objc dynamic var value1: Int { get { integer(forKey: "value1") } set { set(newValue, forKey: "value1") } } static var other: UserDefaults { UserDefaults(suiteName: "other-defaults")! } } struct ContentView: View { private let sub = UserDefaults.other.publisher(for: \.value1).sink { print("SUB", $0) } var body: some View { Button("Add") { UserDefaults.other.value1 += 1 debugPrint("SET", UserDefaults.other.value1) } .onReceive(UserDefaults.other.publisher(for: \.value1)) { debugPrint("UI", $0) } } }
输出结果
SUB 0 "UI" 0 "SET" 1 "UI" 1 "SET" 2 "UI" 2
可以看到,只有onReceive的订阅能响应后续值的更新,直接创建的sink订阅只输出了初始值。
默认standard套件的代码示例
struct ContentView2: View { private let sub = UserDefaults.standard.publisher(for: \.value1).sink { print("SUB", $0) } var body: some View { Button("Add") { UserDefaults.standard.value1 += 1 debugPrint("SET", UserDefaults.standard.value1) } .onReceive(UserDefaults.standard.publisher(for: \.value1)) { debugPrint("UI", $0) } } }
输出结果
SUB 0 "UI" 0 SUB 1 SUB 1 "SET" 1 "UI" 1 "UI" 1 SUB 2 SUB 2 "SET" 2 "UI" 2 "UI" 2
这里所有订阅都能正常触发,虽然存在重复调用的情况,但值更新时都会收到回调。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

