如果没有可选关系属性的值,核心数据不会加载?!?迅速

Posted

技术标签:

【中文标题】如果没有可选关系属性的值,核心数据不会加载?!?迅速【英文标题】:Core Data not loading without a value for optional relationship attribute?!? Swift 【发布时间】:2019-06-17 10:04:35 【问题描述】:

我是 Core Data 的新手,虽然它慢慢变得有意义,但当我离开“可选”时,我在加载初始 数据库 时遇到了问题relationship 没有值的值(这不是可选的吗?)。以下代码有效,但如果我遗漏了一些实例化和定义关系的案例(具体细节如下)。

我正在使用一个类通过 for 循环加载数据,该循环分配初始化值并将它们传递给有效加载数据的方法。首先,加载一个名为 Gender 的实体。

class LoadData

init ()

    for count in 0...3
    
        var text = "Value not found"
        let sortOrder: Int32 = Int32(count)

        switch count
        
        case 0:
            text = "Masculine"
        case 1:
            text = "Neutral"
        case 2:
            text = "Feminine"
        case 3:
            text = "Plural"
        default:
            text = "Value unassigned"
        
        loadGender(text: text, sortOrder: sortOrder)
    

在同一个类和 init 中,一个单独的 for 循环定义值并传递以将上下文保存在 Entity、CellData 中。对于案例 0 到 27 和 28 到 51 中定义的 CellData 条目,我使用谓词来实例化特定的 Gender 条目...

    for count in 0...51
    
        var text = "Cell text not found"
        ...
        var dataToGender: Gender? = nil


        switch count
        
        case 0...27:     // HERE - if case 1...27, data will NOT load

            guard let appDelegate = UIApplication.shared.delegate as? AppDelegate
                else  return 
            let moc = appDelegate.persistentContainer.viewContext
            let request = NSFetchRequest<Gender>(entityName: "Gender")

            let genderToFetch = "Masculine"
            request.predicate = NSPredicate(format: "text == %@", genderToFetch)

            do
            
                let fetched = try moc.fetch(request)
                dataToGender = fetched[0] as Gender
             catch
             fatalError("Failed to fetch employees: \(error)") 

        case 28...51:
            guard let appDelegate = UIApplication.shared.delegate as? AppDelegate
                else  return      // get the app delegate
            let moc = appDelegate.persistentContainer.viewContext
            let request = NSFetchRequest<Gender>(entityName: "Gender")

            let genderToFetch = "Feminine"
            request.predicate = NSPredicate(format: "text == %@", genderToFetch)

            do
            
                let fetched = try moc.fetch(request)
                dataToGender = fetched[0] as Gender
             catch
             fatalError("Failed to fetch employees: \(error)") 

        default: return
        

        ...

...传入方法中,将数据放入上下文并保存到Core Data。

func loadCellData(text: String, sortOrder: Int32, portion: Float, color1: String?, color2: String?, color3: String?, colorRangeLoc1: Int32?, colorRangeLoc2: Int32?, colorRangeLoc3: Int32?, colorRangeLen1: Int32?, colorRangeLen2: Int32?, colorRangeLen3: Int32?, underlineRangeLoc1: Int32?, underlineRangeLoc2: Int32?, underlineRangeLoc3: Int32?, underlineRangeLen1: Int32?, underlineRangeLen2: Int32?, underlineRangeLen3: Int32?, dataToGender: NSObject?)

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

    let entry: CellData = NSEntityDescription.insertNewObject(forEntityName: "CellData", into: context) as! CellData
    ...
    entry.text = text
    ...
    entry.dataToGender = dataToGender as? Gender

    do  try context.save() ; print("saved")
    catch let error as NSError
     print("Could not save. \(error), \(error.userInfo)") 

令人惊讶的是,这很好用——但前提是我为所有 CellData 条目定义了关系。但是,我不希望所有条目都有关系(请参阅评论 // 这里)。案例 0...7 不应该有关系,但如果没有分配任何值,则代码执行良好 - 直到调用 DB 值。经检查,Gender 输入正常,但未将 CellData 条目输入 DB,因此在索引 0 第 0 部分未找到对象时崩溃。

日志中没有错误;我可以在 loadCellData 内打印!?!怎么回事?!?

【问题讨论】:

基本上从Core Data中逐条获取记录是非常昂贵的。很可能您可以通过一次提取和适当的谓词和排序描述符加载所有记录 代码到底应该做什么? 代码/关系应该可以对集合视图的内容进行排序和管理。在 UI 中,用户选择一个 Gender 值,我希望能够获取与 Gender 有关系的 CellData。 【参考方案1】:

基本上,CoreData 中的可选值与 Swift 的可选值不同。整数不应该是可选的,关系也应该是可选的。为了解决这个问题,至少对于整数,应该分配一个不可能的值而不是 nil,并用于检查是否分配了一个值。

虽然我知道这很昂贵,但我没有找到一种方法来将关系分配给 CoreData 中的现有记录而不单独获取记录。

【讨论】:

以上是关于如果没有可选关系属性的值,核心数据不会加载?!?迅速的主要内容,如果未能解决你的问题,请参考以下文章

核心数据中是不是使用了可选属性? [复制]

如何添加和查看核心模型关系的数据

延迟的加载

核心数据反向关系未设置

将属性更改为不再是瞬态的 - 我可以通过轻量级核心数据迁移来做到这一点吗?

在初始加载时快速重置核心数据属性标志?