我的应用程序中有一个类(Swift 3),它包含我从AppDelegate
移出的基本CoreData堆栈。应用程序需要执行的所有操作都在我调用CoreDataHelper
的另一个类中。当应用程序启动时,AppDelegate会创建一个CoreDataHelper(let dataManager = CoreDataHelper()
)的实例,这是与堆栈对话的唯一内容。然后在launchCalculatorViewController()
中,dataManager
向堆栈询问新的LiftEvent
:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let dataManager = CoreDataHelper()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// check if data needs to be loaded and load it if needed...
launchCalculatorViewController()
return true
}
func launchCalculatorViewController() {
self.window = UIWindow(frame: UIScreen.main.bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
if let initialViewController: CalculatorViewController = mainStoryboard.instantiateInitialViewController() as? CalculatorViewController {
// create the liftEvent, the viewModel, and wire it up to the view controller
let liftEvent = dataManager.createNewLiftEvent() // go get me a new LiftEvent
let viewModel = calculatorLiftEventViewModelFromLiftEvent(withLiftEvent: liftEvent, dataManager: dataManager)
initialViewController.viewModel = viewModel
initialViewController.dataManager = dataManager
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}
}
这是createNewLiftEvent()
中的dataManager
方法:
func createNewLiftEvent() -> LiftEvent {
let newLiftEvent = LiftEvent(dataManager: self, insertIntoManagedObjectContext: stack.managedObjectContext)
return newLiftEvent
}
并且LiftEvent
的初始化如下所示:
class LiftEvent: NSManagedObject, LiftEventProtocol {
var dataManager: CoreDataHelper!
override func awakeFromInsert() {
super.awakeFromInsert()
let date = Date()
self.date = date
let defaultUnit = UserDefaults.weightUnit()
if defaultUnit == "kg" {
weight = Measurement(value: 0.0, unit: .kilograms)
liftWeights[defaultUnit] = weight
} else {
weight = Measurement(value: 0.0, unit: .pounds)
liftWeights[defaultUnit] = weight
}
if let defaultFormula = dataManager.fetchDefaultFormula() { // unexpected nil error thrown here
self.formula = defaultFormula // this is an NSManagedObject
}
}
convenience init(dataManager: CoreDataHelper, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
let entity = NSEntityDescription.entity(forEntityName: "LiftEvent", in: context)!
self.init(entity: entity, insertInto: context) // exits after this line
self.dataManager = dataManager // never gets executed so of course it's nil
}
}
我在解开Option值时出现“意外发现的nil”错误,因为此时dataManager
为nil。我尝试在便捷初始化程序中设置它,但self.dataManager = dataManager
从未执行,因为它在self.init
之后立即退出。当然我不能把它放在self.init
之前,因为在设置值之前对象必须存在。
我正在尝试传递dataManager
以确保正在创建的公式(也是NSManagedObject
)和新的LiftEvent
位于同一个托管对象上下文中所以我可以在awakeFromInsert()
中设置它们之间的关系。在尝试这种方法之前它崩溃了,因为LiftEvent
和Formula
是两个不同的managedObjectContexts
(尽管我做了很多工作以确保dataManager
和堆栈只被实例化一次)。上面的方法受到this thread的启发,但我想我可能不理解初始化以及我认为我做过。
如何传入托管对象上下文以创建LiftEvent
,因此它与Formula
位于同一个托管对象上下文中,因此可以设置关系?或者,这是完全错误的方法吗?