引用实例方法需要等效性 (SWIFT)



我正在尝试利用SwiftUI和Combation来存储我的应用程序的用户默认值。查看其他几篇帖子中的建议,我已经更新了我的代码,如下所示。 但是,我现在收到错误"在'主题'上引用实例方法'send(('需要'设置'和'无效'类型是等效的"。 有人建议我在直通主题中将"设置"更改为无效,但是这会在启动时在应用程序中造成硬崩溃 - "致命错误:找不到 Setup.Type 类型的可观察对象。

我有点不知所措...欢迎任何指示。

==============  DataStoreClass ============
import SwiftUI
import Foundation
import Combine
class Setup: ObservableObject {
private var notificationSubscription: AnyCancellable?
let objectWillChange = PassthroughSubject<Setup,Never>()
@UserDefault(key: "keyValueBool", defaultValue: false)
var somevalueBool: Bool {
didSet{
objectWillChange.send()  // <====== Referencing instance method 'send()' on 'Subject' requires the types 'Setup' and 'Void' be equivalent
}
}
init() {
notificationSubscription = NotificationCenter.default.publisher(for: UserDefaults.didChangeNotification).sink { _ in
self.objectWillChange.send()
}
}
}

============= property wrapper ===========
import Foundation
@propertyWrapper
struct UserDefault<T> {
let key: String
let defaultValue: T
var wrappedValue: T {
get {
UserDefaults(suiteName: "group.com.my.app")!.value(forKey: key) as? T ?? defaultValue
} set {
UserDefaults(suiteName: "group.com.my.app")!.set(newValue, forKey: key)
}
}
}

错误来自这样一个事实,即您已将Output类型声明为Setup,但您正在使用Void调用 objectWillChange 。

所以你必须将 self 传递给 objectWillChange:

self.objectWillChange.send(self)

需要注意的重要一点是,您应该不要用didSet而是在willSet中调用objectWillChange

var somevalueBool: Bool {
willSet{
objectWillChange.send(self
}
}

你永远不会设置某个值布尔值,所以这段代码无论如何都不会被调用。

您的设置应大致如下所示:

class Setup: ObservableObject {
private var notificationSubscription: AnyCancellable?
public let objectWillChange = PassthroughSubject<Setup,Never>()
@UserDefault(key: "keyValueBool", defaultValue: false)
var somevalueBool: Bool
init() {
notificationSubscription = NotificationCenter.default.publisher(for: UserDefaults.didChangeNotification).sink { _ in
self.objectWillChange.send(self)
}
}
}

send方法要求您传递主题的输入类型或失败完成。所以你的send线应该通过Setup;

objectWillChange.send(self)

也就是说,在大多数 SwiftUI 代码中,PassthroughSubject<Void, Never>的(这样send()就不需要参数了(。目前尚不清楚您描述的崩溃源是什么;我们需要查看崩溃中涉及的代码才能对其进行调试。到目前为止,我还没有复制它。

SwiftUI 不使用PassthroughSubject,而是使用ObservableObjectPublisher。我很确定这是PassthroughSubject<Void, Never>的别名,但我不确定。ObservableObject协议为您定义了正确的objectWillChange,因此您可以做的最好的事情就是删除您的定义。

出版商是objectWillChange的,顾名思义,它应该以willSet而不是didSet发送,我认为这并不重要,但苹果从didSet改为willSet,我的猜测是他们有一个很好的理由。

最新更新