ios - 使用 CoreData 和依赖注入 - 线程 1:致命错误:init(coder:) 尚未实现
问题描述
我正在尝试学习如何使用 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)
}
}
}
}
家庭VC:
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")
}
持久性管理器:
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
}
解决方案
如果您使用 segues,则从UIViewController
实例化Storyboard
,这是通过init?(coder:)
初始化程序完成的。你让它不可用使得它HomeVC
无法实例化,Storyboard
因为它在那里崩溃。
该属性var persistenceManager: PersistenceManager
使 Swift 无法init(coder:)
从UIViewController
(解释) 继承,因此您必须为自己提供一个,在其中初始化您添加的所有变量,以使其UIViewController
进入可用状态。
尝试使其成为var peristenceManager: PersistenceManager
可选,因为无论如何您稍后都会分配它,或者在同一行中为其分配一个默认值,或者在init?(coder:)
它被初始化时为其分配一个值。super.init(coder:)
也可以在您的内部调用,init?(coder:)
因为它会从情节提要中加载所有设置。
由于Storyboard
您不能在任何初始化程序中提供内容,因此您必须在初始化程序运行后进行设置。您可以使用静态工厂函数来初始化 vc 实例,然后立即设置您想要的内容,然后将 vc 以可用状态返回。
那么如何通过 tabBarController 将 homeVC.persistenceManager = PersistenceManager.shared 直接传递给 HomeVC 来将其转换为 HomeVC(persistenceManager: PersistenceManager.shared) 呢?
您不能使用该初始化程序,因为唯一被调用的是init?(coder:)
初始化程序。您可以将变量更改为:
var persistenceManager: PersistenceManager!
然后你可以在init(coder:)
被调用之后设置变量并且你有你的实例。
这里UITabBarController
初始化了HomeVC
,这个人在这里有同样的问题,在哪里初始化他UIViewController
的嵌入,也许它可以帮助你。答案使用在显示 a 之前正在调用的调用UIViewController
:
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
// Initialization code here.
// Also make sure its only called once if you want
}
UIViewController
如果需要某个选项卡,他甚至会自己构建。
您当然可以像以前一样设置它,因为UITabBarController
尚未显示。保持简单,就像你已经做的那样。
推荐阅读
- javascript - 如何模拟函数,即在 axios promise 的“then”中调用?
- javascript - 滚动导航到顶部
- ios - 如何在页面控件swift上捕获点击事件
- asp.net-mvc-5 - SignalR For ASP.NET MVC with Angular 7(不是 ASP.NET 核心)
- go - 如何构造 time.Time 与时区偏移
- jquery - ChartJS 不显示来自 ASPX 的动态数据
- kognitio - 创建 kognitio 集群后无法运行滑块
- ruby-on-rails - 为什么 RSpec 在 Rails 5 API 指南/教程中如此受欢迎?
- html - 从 HTML 调用函数
- php - 如何使用 PHP SDK Quickbooks 创建多个付款