Mar*_*ark 2 core-data swiftui combine observedobject
这个问题最好用一个例子来解释:
struct MyEditor: View {
@Environment(\.managedObjectContext) var managedObjectContext
@ObservedObject var song: Song
var body: some View {
TextEditor(text: $song.lyrics)
.navigationTitle(song.title)
.onChange(of: song.lyrics) { newValue in
try? managedObjectContext.save()
}
}
}
Run Code Online (Sandbox Code Playgroud)
垃圾邮件感觉不对save,但我想确保数据已存储。这是允许的并且是正确的方法吗?
我能想到的另一种方法是创建一个发布者来平滑保存信号。如果这是正确的方法。我可以从 ObservedObject 检索发布者,还是必须@State为此创建一个不同的属性并用于onChange传递值。
struct MyEditor: View {
@Environment(\.managedObjectContext) var managedObjectContext
@ObservedObject var song: Song
@State private var lyricsPublisher = PassthroughSubject<String, Never>()
var body: some View {
TextEditor(text: $song.lyrics)
.navigationTitle(song.title)
.onChange(of: song.lyrics) { newValue in
lyricsPublisher.send(newValue)
}
.onReceive(lyricsPublisher
.debounce(for: 0.5, scheduler: RunLoop.main)
.removeDuplicates()
) { value in
try? managedObjectContext.save()
}
}
}
Run Code Online (Sandbox Code Playgroud)
这就是宋作为一个人的样子ManagedObject。
@objc(Song)
class Song: NSManagedObject, Identifiable {
@nonobjc class func fetchRequest() -> NSFetchRequest<Song> {
return NSFetchRequest<Scribble>(entityName: "Song")
}
@NSManaged public var id: UUID
@NSManaged public var title: String
@NSManaged public var lyrics: String
}
Run Code Online (Sandbox Code Playgroud)
是的,可以ObservedObject直接使用管理对象的发布者( ),例如
var body: some View {
TextEditor(text: $song.lyrics)
.navigationTitle(song.title)
.onReceive(song.publisher(for: \.lyrics) // << here !!
.debounce(for: 0.5, scheduler: DispatchQueue.main)
.removeDuplicates()
) { value in
try? managedObjectContext.save()
}
}
Run Code Online (Sandbox Code Playgroud)