【问题标题】:Initializing CoreData in macOS在 macOS 中初始化 CoreData
【发布时间】:2018-04-16 18:29:20
【问题描述】:

在 Cocoa 中,Storyboard 的第一个视图控制器将在调用 AppDelegateapplicationDidFinishLaunching 之前调用 viewDidLoad(在第一个视图控制器上)。
由于我在applicationDidFinishLaunching 中获取了我的NSManagedObjectContext,因此我需要等待applicationDidFinishLaunching 才能加载我的数据。

换句话说,在viewDidLoad,我还没有我的NSManagedObjectContext


我现在在做什么:

我在viewDidLoad 中添加了一个applicationDidFinishLaunching 观察者,并在触发时加载数据。

所以(按顺序):
1. ViewController 正在添加一个applicationDidFinishLaunching 观察者。
2. AppDelegates 运行其applicationDidFinishLaunching 并触发观察者。
3. 我可以从我的 ViewController 加载数据。


我意识到我正在中继 viewDidLoad,以便在applicationDidFinishLaunching 之前被调用。如果更改顺序,观察者将添加到applicationDidFinishLaunching 之后,并且不会加载数据。

让我的“CoreDataManager”直接在其init 中从 AppDelegate 获取NSManagedObjectContext 会“更安全”吗?

【问题讨论】:

  • 这里真正的问题是,为什么viewDidLoadapplicationDidFinishLaunching 之前被调用?这不正常。一些奇怪的事情正在发生,Core Data 只是症状,而不是原因。
  • @TomHarrington 恐怕是在可可的土地上:stackoverflow.com/questions/36681587/…
  • 抱歉,我在考虑 iOS。没关系。
  • @TomHarrington 你说得对。这真的很违反直觉,在 Apple 的示例中,它们指示 NSManagedObjectContext 指针在 applicationDidFinishLaunching 中向右传递。

标签: macos core-data


【解决方案1】:

我是否可以建议修改设计,从 AppDelegate 类中删除对核心数据的任何使用,并将任何初始化移动到您的根视图控制器中,然后使用依赖注入将您的托管对象上下文传递给其他视图控制器(或单独的核心数据管理器类实现为单例)。这将使您摆脱此类问题。

【讨论】:

  • 我花了一些时间才意识到这确实是最好的方法。我基本上只是添加了一些解释和代码,但是是的,CoreData 代码可以很容易地移动,它是一个独立的函数。
【解决方案2】:

Joakim Danielson 在这里提供的答案是我最终所做的(信用到期)。

--编辑

最终完全按照 Joakim Danielson 的建议行事。获取上下文的给定代码,默认情况下可能在AppDelegate 中,但它是完全独立的。它真的可以在任何地方移动。
我基本上将以下函数移动到我的CoreDataManager 类中,我在init() 中调用它:

lazy var persistentContainer: NSPersistentContainer = {

    let container = NSPersistentContainer(name: "AppName")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error {
            // Replace this implementation with code to handle the error appropriately.
            fatalError("Unresolved error \(error)")
        }
    })
    return container
}()

另外,不要忘记AppDelegate 中的saveContext() 需要更新(默认情况下它指向自己的getter)。


(上一个答案:)

我已将AppDelegate 中提供的签名lazy var persistentContainer: NSPersistentContainer(通过在创建项目时检查CoreData)更改(某种程度上)为:static var persistentContainer: NSPersistentContainer

static var coreDataContext: NSManagedObjectContext = {

    let container = NSPersistentContainer(name: "AppName")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error {
            // Replace this implementation with code to handle the error appropriately.
            fatalError("Unresolved error \(error)")
        }
    })
    return container.viewContext
}()

我的CoreDataManager(这是一个单例),现在可以使用这个初始化:

class CoreDataManager {

static let shared = CoreDataManager()

weak var context: NSManagedObjectContext!

init() {
    self.context = AppDelegate.coreDataContext
}

使用这种模式(AppDelegate):

static var coreDataContext: NSManagedObjectContext = {...}()

确保块只执行一次。

现在,在任何阶段使用NSManagedObjectContext 都是安全的。

【讨论】:

    猜你喜欢
    • 2019-03-31
    • 2018-06-18
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 2014-10-14
    • 2016-06-14
    相关资源
    最近更新 更多