更改应用程序状态时,CoreData 提取请求 returns 具有 nil 属性的对象
CoreData fetch request returns an object with nil properties when changing app state
我有一些代码可以帮助管理当前的托管对象上下文
var currentContext: NSManagedObjectContext {
if Thread.isMainThread {
return mainContext
} else {
return backgroundContext
}
}
var mainContext: NSManagedObjectContext {
return persistentContainer.viewContext
}
lazy var backgroundContext: NSManagedObjectContext = {
let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
context.parent = mainContext
return context
}()
获取函数
public func entities(_ fetchOptions: FetchOptions) -> [T] {
let fetchRequest = NSFetchRequest<T>(entityName: T.entityName)
switch fetchOptions {
case let .filtered(predicate):
fetchRequest.predicate = predicate
case let .sorted(sortDescriptors):
fetchRequest.sortDescriptors = sortDescriptors
case let .filteredAndSorted(predicate, sortDescriptors):
fetchRequest.predicate = predicate
fetchRequest.sortDescriptors = sortDescriptors
case .all:
fetchRequest.sortDescriptors = []
}
fetchRequest.returnsObjectsAsFaults = false
let context = CoreDataContextProvider.provider.currentContext
return (try? context.fetch(fetchRequest)) ?? []
}
假设我有一个从服务器获取一些数据并将其写入 CoreData 的请求。当我在前台使用该应用程序时,一切正常,但是当我进入后台时,例如,切换到另一个应用程序,然后返回,从当前上下文获取特定实体的请求 returns 类似
SomeEntity {
var property1 = 0;
var property2 = nil;
var property3 = nil;
... etc
}
后台上下文中的数据是正确的,我在切换回主上下文后就得到了这个行为。
我已经尝试在 UIApplication.didEnterBackgroundNotification
和 UIApplication.willEnterForegroundNotification
上保存当前上下文,因此无论如何都会推送更改,但它似乎没有帮助。
此外,我尝试在 NSManagedObject.didSaveObjectsNotification
上合并主要和背景上下文,得到了相同的结果,但我不排除我在这里做错了。
当我只使用主上下文时,一切似乎都工作正常,但我变得严重 UI 偶尔会死机。
解决方案是让主上下文为我做这些合并工作,实际上有一种方法可以创建新的背景上下文,而不会很麻烦:
persistentContainer.newBackgroundContext()
现在一切正常
我有一些代码可以帮助管理当前的托管对象上下文
var currentContext: NSManagedObjectContext {
if Thread.isMainThread {
return mainContext
} else {
return backgroundContext
}
}
var mainContext: NSManagedObjectContext {
return persistentContainer.viewContext
}
lazy var backgroundContext: NSManagedObjectContext = {
let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
context.parent = mainContext
return context
}()
获取函数
public func entities(_ fetchOptions: FetchOptions) -> [T] {
let fetchRequest = NSFetchRequest<T>(entityName: T.entityName)
switch fetchOptions {
case let .filtered(predicate):
fetchRequest.predicate = predicate
case let .sorted(sortDescriptors):
fetchRequest.sortDescriptors = sortDescriptors
case let .filteredAndSorted(predicate, sortDescriptors):
fetchRequest.predicate = predicate
fetchRequest.sortDescriptors = sortDescriptors
case .all:
fetchRequest.sortDescriptors = []
}
fetchRequest.returnsObjectsAsFaults = false
let context = CoreDataContextProvider.provider.currentContext
return (try? context.fetch(fetchRequest)) ?? []
}
假设我有一个从服务器获取一些数据并将其写入 CoreData 的请求。当我在前台使用该应用程序时,一切正常,但是当我进入后台时,例如,切换到另一个应用程序,然后返回,从当前上下文获取特定实体的请求 returns 类似
SomeEntity {
var property1 = 0;
var property2 = nil;
var property3 = nil;
... etc
}
后台上下文中的数据是正确的,我在切换回主上下文后就得到了这个行为。
我已经尝试在 UIApplication.didEnterBackgroundNotification
和 UIApplication.willEnterForegroundNotification
上保存当前上下文,因此无论如何都会推送更改,但它似乎没有帮助。
此外,我尝试在 NSManagedObject.didSaveObjectsNotification
上合并主要和背景上下文,得到了相同的结果,但我不排除我在这里做错了。
当我只使用主上下文时,一切似乎都工作正常,但我变得严重 UI 偶尔会死机。
解决方案是让主上下文为我做这些合并工作,实际上有一种方法可以创建新的背景上下文,而不会很麻烦:
persistentContainer.newBackgroundContext()
现在一切正常