【发布时间】:2020-09-21 20:42:12
【问题描述】:
如何使用 SwiftUI 在模态视图中创建新的 ManagedObject (MO)?
遇到一个奇怪的错误,Xcode 消耗 GB 内存并通过交换文件填满 Mac 上的硬盘。
当在.sheet 修饰符中创建模态视图时,似乎会创建某种无限循环,该循环会用注入该模态视图的 ManagedObject 的副本填充内存。
此示例项目至少说明了部分问题。如果你运行它,你会看到 .sheet 修饰符中调用的方法一遍又一遍地触发。一种理论是,下方显示 ManagedObjects 列表的屏幕会导致两个屏幕之间出现某种循环。
https://github.com/sphericalwave/ChildContextTest
希望在模态屏幕中使用 childContext,因此如果模态视图在未保存 childContext 的情况下被关闭,则任何未保存的更改都将被丢弃。但首先需要清除这个障碍,跨上下文共享 ManagedObject 存在一些挑战。
import CoreData
import SwiftUI
struct CrtFdsUI: View
{
@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: CrtFd.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \CrtFd.scale, ascending: true)])
var crtFds: FetchedResults<CrtFd>
@State var showModal = false
@ObservedObject var absFd: AbsFd
func crtFdModal() -> CrtFdUI {
print("func crtFdModal() -> CrtFdUI")
let cF = CrtFd(scale: 1.0, absFd: absFd, moc: moc)
return CrtFdUI(crtFd: cF)
}
var body: some View {
NavigationView {
VStack {
List {
ForEach(self.crtFds, id: \.objectID) {
CrtFdCell(crtFd: $0)
}
}
.navigationBarTitle("CrtFdsUI")
.navigationBarItems(trailing: PlusBtn(showModal: $showModal))
}
.sheet(isPresented: $showModal) { self.crtFdModal() } //FIXME: Called in endless loop?
}
}
}
这是 managedObjects 的列表。
import CoreData
import SwiftUI
struct CrtFdsUI: View
{
@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: CrtFd.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \CrtFd.scale, ascending: true)])
var crtFds: FetchedResults<CrtFd>
@State var showModal = false
@ObservedObject var absFd: AbsFd
func crtFdModal() -> CrtFdUI {
print("func crtFdModal() -> CrtFdUI")
let cF = CrtFd(scale: 1.0, absFd: absFd, moc: moc)
return CrtFdUI(crtFd: cF)
}
var body: some View {
NavigationView {
VStack {
List {
ForEach(self.crtFds, id: \.objectID) {
CrtFdCell(crtFd: $0)
}
}
.navigationBarTitle("CrtFdsUI")
.navigationBarItems(trailing: PlusBtn(showModal: $showModal))
}
.sheet(isPresented: $showModal) { self.crtFdModal() }
}
}
}
【问题讨论】:
标签: core-data swiftui nsmanagedobjectcontext