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

标签 swift swiftui combine

我正在尝试利用 SwiftUI 和 Combine 来存储我的应用程序的用户默认值。查看其他几篇文章中的建议,我已经更新了我的代码,如下所示。但是,我现在收到“在‘Subject’上引用实例方法‘send()’需要类型‘Setup’和‘Void’等效”的错误。有人建议我在 PassthroughSubject 中将“Setup”更改为 void,但是这会在应用程序启动时造成严重崩溃 - “ fatal error :未找到 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)

需要注意的重要一点是,您应该调用 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)
        }
    }
}

关于swift - 引用实例方法需要等效性 (SWIFT),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58159101/

相关文章:

swift - 第一次向文本字段添加文本 [Swift]

swift - 从 swift/firebase 闭包内部修改变量

ios - 什么是 PassthroughSubject 和 CurrentValueSubject

ios - 当 MIDI 目标或源更改时收到通知

ios - 我可以为图像设置动画吗 iOS8 LaunchScreen.xib

swift - 一起使用 Timer 和 ScrollView 的奇怪错误或问题

ios - SwiftUI:fullScreenCover 的半透明背景

ios - 相机预览上的 SwiftUI 位置叠加

swift - 结合 SwiftUI 远程获取数据 - ObjectBinding 不更新 View

SwiftUI - 当加载 View 后更新属性时,不会调用 onReceive 来更改 ObservableObject 属性