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

Posted

技术标签:

【中文标题】我使用 coreData 保存数据,但对象保持为零【英文标题】:I save data using coreData but yet objects stay nil 【发布时间】:2017-07-18 08:37:23 【问题描述】:

我正在使用核心数据将信息保存到对象,但是当我尝试使用它时,程序崩溃并显示“致命错误:在展开可选值时意外发现 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"

这是获取函数

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

【问题讨论】:

这意味着有些东西是零。尝试找出哪个属性为 nil,究竟是哪一行导致了崩溃。 self.title.text = item.title ,其余部分也是如此 但这是否意味着item 为零? item.title 是 nil,还是 self.title 是 nil?这是不同的情况,无论问题是在 CoreData 端还是在您的 Cell 端。 我刚刚发现我的插座没有连接!谢谢你指出这一点。 【参考方案1】:

在从项目中获取数据之前,请保存上下文。在您的场景中,在 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()
            
        
    


【讨论】:

仍然崩溃,当我调试数据保存但当我尝试使用它时崩溃【参考方案2】:

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

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

ad.saveContext()

saveContext() 就像 db 术语中的提交语句。为了使用上述内容,请在类定义之外的 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

【讨论】:

【参考方案3】:

我认为您忘记在尝试获取对象/实体的类中创建 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
    

希望对你有所帮助

【讨论】:

以上是关于我使用 coreData 保存数据,但对象保持为零的主要内容,如果未能解决你的问题,请参考以下文章

核心数据上下文不保存

CoreData:过滤 FetchRequest 结果为零

iOS - Swift CoreData 中的 ManagedObjectContext 为零

核心数据:我的托管对象上的托管对象上下文为零

尝试在块中保存对象时崩溃。 (CoreData 无法满足...的错误)

Swift:检查变量是不是为零