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

引用实例方法需要等效性(SWIFT),swift,swiftui,combine,Swift,Swiftui,Combine,我正试图利用SwiftUI并结合起来为我的应用程序存储用户默认值。看看其他几篇文章中的建议,我已经更新了我的代码,如下所示。但是,我现在得到的错误是“Subject”上的“reference instance method'send()”要求类型“Setup”和“Void”等效”。有人建议我在PassthroughSubject中将“Setup”更改为void,但是这会在应用程序启动时导致硬崩溃-“致命错误:找不到Setup.type类型的可观察对象。” 我有点不知所措。。。欢迎任何指点

我正试图利用SwiftUI并结合起来为我的应用程序存储用户默认值。看看其他几篇文章中的建议,我已经更新了我的代码,如下所示。但是,我现在得到的错误是“Subject”上的“reference instance method'send()”要求类型“Setup”和“Void”等效”。有人建议我在PassthroughSubject中将“Setup”更改为void,但是这会在应用程序启动时导致硬崩溃-“致命错误:找不到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)
        }
    }
}
======================数据存储类============
导入快捷键
进口基金会
进口联合收割机
类设置:ObserveObject{
私有var通知订阅:是否可取消?
let objectWillChange=PassthroughSubject()
@UserDefault(键:“keyValueBool”,默认值:false)
var somevalueBool:Bool{
迪塞特{

objectWillChange.send()//方法要求您传递主题的输入类型,或失败完成。因此您的
发送
行应通过
设置

objectWillChange.send(self)

也就是说,在大多数SwiftUI代码中,
PassthroughSubject
(因此
send()
不需要参数)。不清楚您描述的崩溃的来源是什么;我们需要查看崩溃中涉及的代码才能调试它。到目前为止,我还没有复制它。

SwiftUI没有使用
PassthroughSubject
,它使用的是
observeObjectPublisher
。我非常确定这是
PassthroughSub的别名object
但我不确定。
observegeobject
协议定义了一个正确的
对象,它将为您更改
,因此您可以做的最好的事情是删除您的定义


发布者是
objectWillChange
,顾名思义,它应该是
willSet
而不是
didSet
,我认为这并不重要,但苹果公司从
didSet
改为
willSet
,我猜他们有一个很好的理由。

错误来自于你的decl是否将您的
输出
键入为
设置
,但您正在调用objectWillChange并使用
Void

因此,您必须将自我传递给objectWillChange:

self.objectWillChange.send(self)
需要注意的重要一点是,您应该调用
objectWillChange
而不是在
didSet
中,而是在
willSet
中:

var somevalueBool: Bool {
    willSet{
        objectWillChange.send(self
    }
}
您从未设置过somevalueBool,因此这段代码无论如何都不会被调用

您的设置大致如下所示:

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)
        }
    }
}
类设置:ObservableObject{
私有var通知订阅:是否可取消?
public let objectWillChange=PassthroughSubject()
@UserDefault(键:“keyValueBool”,默认值:false)
var somevalueBool:Bool
init(){
notificationSubscription=NotificationCenter.default.publisher(for:UserDefaults.didChangeNotification).sink{uu}in
self.objectWillChange.send(self)
}
}
}

我不是最好的联合编码员,但根据你对
的定义,你告诉编译器,在
发送中,你将传递一个
设置
实例,我想,`objectWillChange.send([在这里插入你的设置实例])`。我只是在你的代码中看不到这个“设置实例”到底是什么是。谢谢,这似乎解决了可能的主要问题。它仍然没有像我想的那样工作,因为我更改值的SwiftUI代码似乎没有“触发”willSet()代码。