如何在 AppDelegate 中初始化 Core Data 的持久化容器并在整个应用程序中使用它?
Posted
技术标签:
【中文标题】如何在 AppDelegate 中初始化 Core Data 的持久化容器并在整个应用程序中使用它?【英文标题】:How do I initialize the Core Data's persistent container in AppDelegate and use it throughout the app? 【发布时间】:2020-08-02 16:17:45 【问题描述】:我正在尝试在整个应用程序的多个视图控制器中使用 NSPersistentContainer
来获取 Core Data。
最初,我在单个视图控制器中设置了容器,效果很好:
第一个视图控制器
var container: NSPersistentContainer!
container = NSPersistentContainer(name: "MyCoreData")
container.loadPersistentStores storeDescription, error in
self.container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
if let error = error
print("Unresolved error \(error.localizedDescription)")
但是,我根据苹果的documentation将此代码迁移到AppDelegate
:
AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate
var window: UIWindow?
lazy var persistentContainer: NSPersistentContainer =
let container = NSPersistentContainer(name: "MyCoreData")
container.loadPersistentStores description, error in
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
if let error = error
fatalError("Unable to load persistent stores: \(error)")
return container
()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
if let firstVC = window?.rootViewController as? FirstViewController
firstVC.container = persistentContainer
if let secondVC = window?.rootViewController as? SecondViewController
secondVC.container = persistentContainer
return true
我的每个视图控制器现在都有一个名为container
的NSPersistentContainer
类型的变量。但是,当我加载视图控制器时,出现以下错误:
在隐式展开可选值时意外发现 nil
此错误指向container.viewContext
所在的位置。更具体地说:
fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: container.viewContext, sectionNameKeyPath: "title", cacheName: nil)
我不确定我是否收到来自 rootViewController
的错误,因为我没有一个根视图控制器,因为我正在使用标签栏控制器。
【问题讨论】:
你应该初始化persistentContainer一次(AppDelegate很好)并在你的viewControllers中传递一个对managedObjectContext的引用。使用 managedObjectContext 访问您的实体、编辑、删除和保存它们。 【参考方案1】:我的建议是UIViewController
扩展中的 lazy instantiated 计算属性,实际上您只需要托管对象上下文。
extension UIViewController
var context : NSManagedObjectContext
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.persistentContainer.viewContext
您还可以添加save
函数。
【讨论】:
我是否应该不初始化持久化容器let container = NSPersistentContainer(name: "MyCoreData")
,而只使用context
?如何在没有容器的情况下加载持久存储,就像使用 container.loadPersistentStores
一样?我应该把你的代码放在AppDelegate.swift
中吗?
使用你的 AppDelegate 版本和这个扩展。该属性被初始化一次,您可以在UIViewController
的所有子类中使用它。您可以将代码放入AppDelegate
文件或额外文件Extensions.swift
我收到了错误Extensions must not contain stored properties
对不起,我的错,它必须是一个计算属性,请参阅编辑。以上是关于如何在 AppDelegate 中初始化 Core Data 的持久化容器并在整个应用程序中使用它?的主要内容,如果未能解决你的问题,请参考以下文章
从AppDelegate中访问NavigationController指向的初始视图
iOS 如何在 AppDelegate 中以编程方式设置侧边栏菜单?
在 Core Data 中从 AppDelegate 执行回滚功能时需要访问 ManagedObjectContext 的同一实例
Singleton 类 DataLoader - 在 AppDelegate 中从 Core Data 设置值,但无法访问其他类中的 DataLoader 变量