使用CoreData和依赖注入-线程1:致命错误:尚未实现init(coder :)

时间:2018-08-19 14:06:10

标签: ios swift core-data dependency-injection persistence

我正在尝试学习如何使用CoreData以及实现它的正确方法,目前,我已经在youtube上观看了此视频(下面的链接)。目前,这一切都说得通,但是,当我从一个viewController转到HomeVC(属于选项卡栏控制器的一部分)时,出现以下错误。有谁知道为什么吗?非常感谢您的帮助,非常感谢!

https://www.youtube.com/watch?v=OYRo3i9z-lM

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
    \\ Thread 1: Fatal error: init(coder:) has not been implemented
}

首页功能:

func toHome() {
    self.dismiss(animated: true) {
        if let destVC = UIStoryboard(name: "Home", bundle: nil).instantiateViewController(withIdentifier: "TabBarHomeVC") as? UITabBarController {
            if let homeVC = destVC.viewControllers?.first as? HomeVC {
                homeVC.persistenceManager = PersistenceManager.shared
                self.present(destVC, animated: true, completion: nil)
            }
        }
    }
}

HomeVC:

class HomeVC: UIViewController {

    var persistenceManager: PersistenceManager

    init(persistenceManager: PersistenceManager) {
        self.persistenceManager = persistenceManager
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

PersistenceManager:

import Foundation
import CoreData

final class PersistenceManager {

    private init() {}
    static let shared = PersistenceManager()

    lazy var persistentContainer: NSPersistentContainer = {

        let container = NSPersistentContainer(name: "CoreDataApp")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {

                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

    lazy var context = persistentContainer.viewContext
}

1 个答案:

答案 0 :(得分:3)

如果您使用segues,则会从UIViewController实例化Storyboard,这是通过init?(coder:)初始化程序完成的。您将其设置为不可用将导致HomeVC无法从Storyboard实例化,因为它在那里崩溃了。

属性var persistenceManager: PersistenceManager使Swift无法从init(coder:)explanation)继承UIViewController,因此您必须为自己提供一个,在其中初始化所有添加的变量,使UIViewController进入可用状态。

请尝试使var peristenceManager: PersistenceManager为可选,因为无论如何稍后要分配它,或者在同一行中为其分配默认值,或者在init?(coder:)期间为其分配一个值,以使其初始化。还要在super.init(coder:)内部调用init?(coder:),因为它会从情节提要中加载所有设置。

使用Storyboard不能在任何初始化程序中提供东西,因此必须在初始化程序运行后进行设置。您可以使用静态工厂函数在其中初始化vc实例,然后立即设置所需的值,然后以可用状态返回vc。

  

那么如何通过将其通过tabBarController直接传递到HomeVC来使homeVC.persistenceManager = PersistenceManager.shared成为HomeVC(persistenceManager:PersistenceManager.shared)?

您不能使用该初始化程序,因为唯一被调用的是init?(coder:)初始化程序。您可以将变量更改为:

var persistenceManager: PersistenceManager!

然后,您可以在调用init(coder:)之后拥有实例的情况下设置变量。

这里UITabBarController初始化了HomeVCthis guy here遇到了同样的问题,在哪里初始化他的UIViewController被嵌入,也许可以帮到您。答案使用的呼叫是在显示UIViewController之前被呼叫的:

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    // Initialization code here.
    // Also make sure its only called once if you want
}

如果需要某个标签,他甚至可以自己构造UIViewController

由于UITabBarController尚未显示,您当然可以像现在一样进行设置。像您已经做的那样保持简单。