Swift核心数据,从警报视图中保存时崩溃

时间:2016-10-06 21:59:44

标签: swift core-data

我有一个适用于Objective C的应用程序,现在我将其更新为Swift 3.我有一个警报视图添加到表格,应用程序在let newGauge = Gauge(context: self.coreDataStack.context)崩溃。

我附加了Core Data Stack和AppDelegate,我的segues正常工作并将coreDataStack表单视图传递给view。我可能错过了明显的,但看不到它。欢迎提供帮助。

AppDelegate.swift:

//
//  AppDelegate.swift
//  transectraingauges
//
//  Created by Hugh Chare on 9/27/16.
//  Copyright © 2016 Hugh Chare. All rights reserved.
//

import UIKit
import CoreData
import Foundation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    lazy var coreDataStack = CoreDataStack()

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

        let navigationController = window!.rootViewController as! UINavigationController
        let listViewController = navigationController.topViewController as! ViewController
        listViewController.coreDataStack = coreDataStack

        return true
    }

    private func applicationWillResignActive(application: UIApplication) {
    }

    private func applicationDidEnterBackground(application: UIApplication) {
    }

    private func applicationWillEnterForeground(application: UIApplication) {
    }

    private func applicationDidBecomeActive(application: UIApplication) {
    }

    private func applicationWillTerminate(application: UIApplication) {
        coreDataStack.saveContext()
    }
}

CoreDataStack.swift:

//
//  CoreDataStack.swift
//  transectraingauges
//
//  Created by Hugh Chare on 1/27/15.
//  Copyright (c) 2015 Hugh Chare. All rights reserved.
//

import CoreData

class CoreDataStack {

    let modelName = "RainGauges"

    lazy var context: NSManagedObjectContext = {

        var managedObjectContext = NSManagedObjectContext(
            concurrencyType: .mainQueueConcurrencyType)

        managedObjectContext.persistentStoreCoordinator = self.psc
        return managedObjectContext
    }()

    private lazy var psc: NSPersistentStoreCoordinator = {

        let coordinator = NSPersistentStoreCoordinator(
            managedObjectModel: self.managedObjectModel)

        let url = self.applicationDocumentsDirectory
            .appendingPathComponent("RainGauges.sqlite")

        do {
            let options =
                [NSMigratePersistentStoresAutomaticallyOption : true]

            try coordinator.addPersistentStore(
                ofType: NSSQLiteStoreType, configurationName: nil, at: url,
                options: options)
        } catch  {
            print("Error adding persistent store.")
        }

        return coordinator
    }()

    private lazy var managedObjectModel: NSManagedObjectModel = {

        let modelURL = Bundle.main
            .url(forResource: self.modelName,
                            withExtension: "momd")!
        return NSManagedObjectModel(contentsOf: modelURL)!
    }()

    private lazy var applicationDocumentsDirectory: NSURL = {
        let urls = FileManager.default.urls(
            for: .documentDirectory, in: .userDomainMask)
        return urls[urls.count-1] as NSURL
    }()

    func saveContext () {
        if context.hasChanges {
            do {
                try context.save()
            } catch let error as NSError {
                print("Error: \(error.localizedDescription)")
                abort()
            }
        }
    }
}

GaugeTableViewController.swift

//
//  GaugeTableViewController.swift
//  transectraingauges
//
//  Created by Hugh Chare on 9/27/16.
//  Copyright © 2016 Hugh Chare. All rights reserved.
//

import UIKit
import CoreData

class GaugeTableViewController: UIViewController,  NSFetchedResultsControllerDelegate, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet var tableView:UITableView!

    var newGaugeTextField: UITextField!
    var newGaugeName: String!

    var editedGauge: Gauge!

    var coreDataStack: CoreDataStack!
    var context: NSManagedObjectContext!
    var fetchedResultController:NSFetchedResultsController<Gauge> = NSFetchedResultsController()

    override func viewDidLoad() {

        super.viewDidLoad()

    }

加上获取结果控制器等的标准代码,

 @IBAction func addGauge(sender: AnyObject) {
     let alert = UIAlertController(title: "New Gauge", message: "Add new gauge", preferredStyle: UIAlertControllerStyle.alert)

    let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: {(action: UIAlertAction!) in

    })

    let saveAction = UIAlertAction(title: "Save", style: .default, handler: {(action: UIAlertAction!) in
        self.newGaugeTextField = alert.textFields![0]

        if self.newGaugeTextField != nil {
            self.newGaugeName = self.newGaugeTextField.text}

        else {
            self.newGaugeName = "Unknown"
        }

        let newGauge = Gauge(context: self.coreDataStack.context)
        newGauge.gauge = self.newGaugeName

        self.tableView.reloadData()

    })

    alert.addTextField {
        (textField: UITextField!) in
    }

    alert.addAction(cancelAction)
    alert.addAction(saveAction)

    self.present(alert, animated: true, completion: nil)
}

1 个答案:

答案 0 :(得分:0)

看起来你没有设置变量coreDataStack。声明像

这样的变量时
var coreDataStack: CoreDataStack!

感叹号表示它是一个隐式解包的可选项。基本上它不会标记任何编译器错误,因为你已经声明它将在创建时为零,而且你肯定会在使用它之前设置它。这就是你在

上崩溃的原因
let newGauge = Gauge(context: self.coreDataStack.context)

因为coreDataStack仍然是零。

要修复此问题,请在声明时初始化coreDataStack

var coreDataStack = CoreDataStack()

或使用prepareForSegue或类似的东西传递CoreDataStack实例。在访问变量之前,请确保变量已初始化。

希望这有帮助! :)