初始化AppDelegate中的托管contect,以供其他ViewController



我想初始化托管对象,但是我总是会遇到此错误:

线程1:致命错误:未包装时意外发现了无 可选值

我想使用核心数据/托管对象的ViewController不是我的启动ViewController,而是我通过启动ViewController访问的另一个(Portfoliovc)。

这是我的代码:

import Foundation
import CoreData
class DatabaseController {
    private let modelName: String
    init(modelName: String) {
        self.modelName = modelName
    }
    lazy var managedContext: NSManagedObjectContext = {
        return self.storeContainer.viewContext
    }()
    private lazy var storeContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: self.modelName)
        container.loadPersistentStores { (storeDescription, error) in
            if let error = error as NSError? {
                print("Unresolved error (error), (error.userInfo)")
            }
        }
        return container
    }()
    func saveContext () {
        guard managedContext.hasChanges else { return }
        do {
            try managedContext.save()
        } catch let error as NSError {
            print("Unresolved error (error), (error.userInfo)")
        }
    }
}

这是我的AppDelegate:

import UIKit
import CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    lazy var coreDataStack = DatabaseController(modelName: "Portfolio")
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        guard let navController = window?.rootViewController as? UINavigationController,
            let viewController = navController.topViewController as? PortfolioVC else {
                return true
        }
        viewController.managedContext = coreDataStack.managedContext
        return true
    }
    func applicationWillResignActive(_ application: UIApplication) {
    }
    func applicationDidEnterBackground(_ application: UIApplication) {
        coreDataStack.saveContext()
    }
    func applicationWillEnterForeground(_ application: UIApplication) {
    }
    func applicationDidBecomeActive(_ application: UIApplication) {
    }
    func applicationWillTerminate(_ application: UIApplication) {
        coreDataStack.saveContext()
    }

}

这是portfoliovc中的代码:

导入Uikit导入Coredata

class PortfolioVC: UIViewController {

    var managedContext: NSManagedObjectContext!
    var namePortfolio: NamePortfolio?
override func viewDidLoad() {
        super.viewDidLoad()
        tableViewPortfolio.dataSource = self
        let standardPortfolio = "Watchlist"
        let fetchRequest: NSFetchRequest<NamePortfolio> = NamePortfolio.fetchRequest()
        fetchRequest.predicate = NSPredicate(format: "%K == %@", #keyPath(NamePortfolio.name), standardPortfolio)
        do {
            let results = try managedContext.fetch(fetchRequest) // here I get the error (managedContext = nil)
            if results.count > 0 {
                // Portfolio already created
                namePortfolio = results.first
            } else {
                // no Portfolio
                namePortfolio = NamePortfolio(context: managedContext)
                namePortfolio?.name = standardPortfolio
                try managedContext.save()
            }
        }  catch let error as NSError {
            print("Could not fetch (error), (error.userInfo)")
        }
    }

非常感谢您的帮助!

didFinishLaunchingWithOptions中的代码运行时,尚未将投资组合添加到导航控制器堆栈(甚至是实例化)中,因此后卫会失败。有两种方法可以将ManagedContext到投资组合:

a)将其传递到didfinishlaunchingwithoptions中的启动视图控制器,然后使用PreparforForsegue将其从那里传递到投资组合。即使您只需要将其传递到Portfolio VC。

b)在Portfoliovc中,获取对AppDelegate的引用,然后从那里获取the MandedContext。

    if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
        managedContext = appDelegate.coreDataStack.managedContext
    }

观点对哪种是更好的设计模式。

最新更新