如何将 ManagedObjectContext 快速传递给根视图控制器

Posted

技术标签:

【中文标题】如何将 ManagedObjectContext 快速传递给根视图控制器【英文标题】:How to pass the ManagedObjectContext to the root view controller in swift 【发布时间】:2015-11-17 12:07:32 【问题描述】:

我在 AppDelegate 之外创建了一个单独的 CoreDataStack.swift 对象,以便在使用 CoreData 时遵循此处的大部分建议。但是如何将 MOC 传递给 AppDelegate 中的 rootViewController?我需要向 AppDelegate 或 ViewController 添加代码吗?感谢任何可以在 Swift 中帮助我的人,因为很多旧的 ObjC 不适合我!

我的 CoreDataStack 包括 MOC

  lazy var managedObjectContext: NSManagedObjectContext = 
let managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) //
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
return managedObjectContext
()

AppDelegate 有一个创建一些数据的方法,在 didFinishLaunchingWithOptions 中我可以打印到控制台以查看它的工作情况

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 

    let fetchRequest = NSFetchRequest(entityName: "WordList")
    do 
        let results = try coreDataStack.managedObjectContext.executeFetchRequest(fetchRequest)
        if results.count == 0 
            addTestData()
        

     catch 
        fatalError("Error fetching data!")
    

    do 
        if let results = try coreDataStack.managedObjectContext.executeFetchRequest(fetchRequest) as? [NSManagedObject]  //cast to an array of NSManagedObject
            for result in results 
                if let listName = result.valueForKey("listName") as? String 
                    print("Got a '\(listName)'")
                
            
        
     catch 
        print("There was a fetch error")
    

// WHAT CODE HERE WILL PASS THE MOC TO THE ROOT VC?

return true

我在导航控制器中嵌入了一个简单的 TableViewController

import UIKit
import CoreData

class WordListsTableViewController: UITableViewController 

var coreDataStack: CoreDataStack!
var wordLists = [WordList]()

override func viewDidLoad() 
    super.viewDidLoad()

    title = "Word Lists"
    navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem:    .Add, target: self, action: "viewWordList")


override func viewWillAppear(animated: Bool) 
    super.viewWillAppear(animated)

//  DO I NEED CODE HERE TO CALL THE MOC?

    reloadData()
    tableView.reloadData()


func reloadData() 
    let fetchRequest = NSFetchRequest(entityName: "WordList")

    do 
        if let results = try coreDataStack.managedObjectContext.executeFetchRequest(fetchRequest) as? [WordList] 
            wordLists = results
        
     catch 
        fatalError("There was an error fetching wordLists!")
    

【问题讨论】:

【参考方案1】:

有几种方法可以访问托管对象上下文。如果您在 AppDelegate 中定义了managedObjectContext,您可以使用:

let appDelegate = UIApplicationDelegate.sharedApplication().delegate as! AppDelegate
let managedObjectContext = appDelegate.managedObjectContext
managedObjectContext.doStuff()

通过视图控制器传递managedObjectContext 的第二种方法是创建UIViewController 的扩展。

extension UIViewController 
    lazy var managedObjectContext: NSManagedObjectContext 
        // Create core data stack or use singleton object
        return coreDataStack.managedObjectContext
    

这样做可以访问UIViewController 的每个子类上的 managedObjectContext。然后你可以写:

override func viewWillAppear(animated: Bool) 
    super.viewWillAppear(animated)
    self.managedObjectContext.doSomething()

通过以任何这些方式访问 managedObjectContext,您可以在您的 rootViewController 和您创建的任何 UIViewController 中获得 managedObjectContext

【讨论】:

谢谢!我在 WordListsTableViewController 的底部添加了扩展,但 reloadData() 中的获取请求仍然给出错误“在展开可选值时意外发现 nil”。 AppDelegate 或 ViewWillAppear 中应该有什么? 不,只需确保您的 CoreDataStack 已初始化,并且 managedObjectContext 在您的扩展程序中已初始化。 我看不到是否已初始化。我应该在 viewWIllAppear 中替换 reloadData() 吗? 我现在在扩展中添加了 var coreDataStack = CoreDataStack() 并在 tableviewController 中获取数据。感谢您的帮助说。

以上是关于如何将 ManagedObjectContext 快速传递给根视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

将 UITabBarController 与内部 UINavigationControllers 一起使用时如何共享 ManagedObjectContext

如果它是子视图控制器,如何将 AppDelegate 中的 managedObjectContext 传递给正确的视图控制器?

如何使用 managedObjectContext 来使用实体?

将 ManagedObjectContext 传递/注入到视图控制器中

将 managedObjectContext 发送到 viewController 崩溃

如何观察 NSManagedObject 是不是从 managedObjectContext 中移除