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