gpt4 book ai didi

swift - 为什么用户默认发布者多次触发

转载 作者:行者123 更新时间:2023-12-04 08:10:56 25 4
gpt4 key购买 nike

我订阅了内置的 User Defaults 扩展,但它似乎不必要地多次触发。
这是我正在使用的代码:

import Combine
import Foundation
import PlaygroundSupport

extension UserDefaults {

@objc var someProperty: Bool {
get { bool(forKey: "someProperty") }
set { set(newValue, forKey: "someProperty") }
}
}

let defaults = UserDefaults.standard

defaults.dictionaryRepresentation().keys
.forEach(defaults.removeObject)

print("Before: \(defaults.someProperty)")

var cancellable = Set<AnyCancellable>()

defaults
.publisher(for: \.someProperty)
.sink { print("Sink: \($0)") }
.store(in: &cancellable)

defaults.someProperty = true
cancellable.removeAll()

PlaygroundPage.current.needsIndefiniteExecution = true
这打印:
Before: false
Sink: false
Sink: true
Sink: true
为什么它会触发水槽 3 次而不是一次?
我也许可以理解它在订阅时触发,这令人困惑,因为它似乎不是 PassthroughSubject或任何这方面的文件。然而,真正让我困惑的是它第三次触发。
更新:
这很奇怪,但似乎初始值被考虑到新/旧比较中:
defaults.someProperty = false
defaults.someProperty = true
defaults.someProperty = false
defaults.someProperty = true

print("Initial: \(defaults.someProperty)")

defaults
.publisher(for: \.someProperty, options: [.new])
.sink { print("Sink: \($0)") }
.store(in: &cancellable)

defaults.someProperty = true
以上将打印看起来不错的:
Initial: true
Sink: true
但是当初始值与您设置的不同时:
defaults.someProperty = false
defaults.someProperty = true
defaults.someProperty = false
defaults.someProperty = true
defaults.someProperty = false

print("Initial: \(defaults.someProperty)")

defaults
.publisher(for: \.someProperty, options: [.new])
.sink { print("Sink: \($0)") }
.store(in: &cancellable)

defaults.someProperty = true
上面会奇怪地打印:
Initial: false
Sink: true
Sink: true
这是不直观的,因为它将初始值视为 [.new] 的触发器。 ,然后再次比较设置的内容。

最佳答案

第一个发布的值是您订阅时的初始值,如果您不想接收初始值,您可以在选项中指定它(它们是 NSKeyValueObservingOptions ):

defaults
.publisher(for: \.someProperty, options: [.new])
.sink { print("Sink: \($0)") }
.store(in: &cancellable)
每个新值确实发布了两次,但您可以删除重复项:
defaults
.publisher(for: \.someProperty, options: [.new])
.removeDuplicates()
.sink { print("Sink: \($0)") }
.store(in: &cancellable)
这会给你你想要的行为。
更新:
如果你这样定义你的扩展:
extension UserDefaults {

@objc var someProperty: Bool {
bool(forKey: "someProperty")
}
}
然后使用以下方法设置值:
defaults.set(false, forKey: "someProperty")
值仅发布一次。

关于swift - 为什么用户默认发布者多次触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65965666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com