我使用coreData保存数据但是对象保持为零

时间:2017-07-18 08:37:24

标签: ios swift core-data swift3

我正在使用核心数据将信息保存到对象中,但是当我尝试使用它时,程序崩溃并说“致命错误:在解开可选值时意外发现nil”#34;

这是我生成的数据

func generateTestData()
{
    let item = Item(context: context)
    item.title = "New Iphone 7s"
    item.price = 2000
    item.details = "I wish it's something that is worth to apple , unline Iphone 7"


    let item2 = Item(context: context)
    item2.title = "Beach House in France"
    item2.price = 3000000
    item2.details = "I will live there for the rest of my Life , untill then i don't have a life"
}

这是获取功能

func attemptFetch()
{
    let fetchRequest :NSFetchRequest<Item> = Item.fetchRequest()
    let datasort = NSSortDescriptor(key: "created", ascending: false)
    fetchRequest.sortDescriptors = [datasort]
    let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
    self.controller = controller

    do{
       try controller.performFetch()
    }
    catch{
        let error = error as NSError
        print(error.debugDescription)
    }
}

当我尝试更新我的视图时崩溃发生在这里

 func configureCell(cell : objectItemCell , indexPath :IndexPath)
{
    let item  = controller.object(at:indexPath)
    cell.configureCell(item: item)
}

UITableViewCell类

func configureCell(item : Item)
{
    self.title.text = item.title
    self.price.text = "$\(item.price)"
    self.details.text = item.details
}

3 个答案:

答案 0 :(得分:2)

在从项目获取数据之前,请保存上下文。在您的场景中,在generateTestData()中,执行context.save(),可能是您的应用程序崩溃,因为您没有保存数据并尝试获取哪个返回nil,

func generateTestData()
{
let item = Item(context: context)
item.title = "New Iphone 7s"
item.price = 2000
item.details = "I wish it's something that is worth to apple , unline Iphone 7"


let item2 = Item(context: context)
item2.title = "Beach House in France"
item2.price = 3000000
item2.details = "I will live there for the rest of my Life , untill then i don't have a life"
saveContext() // save data that you initialised
}

// MARK: - Core Data Saving support
func saveContext () {
    if #available(iOS 10.0, *) {
        let context = persistentContainer.viewContext
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    } else {
        // Fallback on earlier versions
        if managedObjectContext.hasChanges {
            do {
                try managedObjectContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nserror = error as NSError
                NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
                abort()
            }
        }
    }

}

答案 1 :(得分:0)

就iOS中的Core数据而言,当您使用generateTestData()时,数据将在NSManagedObjectContext中创建。仅仅因为它驻留在NSManagedObjectContext中并不意味着它被保存在SQLite中。

enter image description here

要将数据保存到SQLite中(持久性所需,因此您不必每次都运行generateTestData()),请使用

ad.saveContext()

saveContext()类似于db术语中的commit语句。要使用上述内容,请在类定义之外的AppDeligate.swift中声明以下内容,以便可以在控制器中访问上下文。

let ad = UIApplication.shared.delegate as! AppDelegate
let contextAP = ad.persistentContainer.viewContext
  

注意:执行上述操作会在SQLite中保存数据,但使用saveContext()运行generateTestData()两次使用相同的数据将在SQLite中创建重复记录。

图片参考:https://www.objc.io/images/issue-4/stack-simple-9af1e89d.png

答案 2 :(得分:0)

我想您忘记在尝试获取对象/实体的类中创建一个managedObjectContext

import CoreData

sampleClass: UITableViewController, UITableViewDataSource ... {

    var context: NSManagedObjectContext!

    override func viewDidLoad() {
       super.viewDidLoad()

       let appDelegate = UIApplication.shared.delegate as! UIAppDelegate
       context = appDelegate.persistentContainer.viewContext
    }

    funcAttemptFetch() {
        // your code
    }

希望这会对你有所帮助