【问题标题】:array items not saved properly in core data entity数组项未正确保存在核心数据实体中
【发布时间】:2016-11-14 03:47:41
【问题描述】:

我的问题是我的字符串数组只有最后一项保存在所需的核心数据实体中。

我有一个名为“itemNames”的多维数组。我将此数组 flatMap 到一个简单的一维数组以遍历它。 该循环为每个项目创建一个 newItem,该项目保存在属性“calc_item”的核心数据实体“CALC_VALUES”中。

newItem 的控制台输出看起来像切面一样。

但是,当我加载实体“CALC_VALUES”的核心数据条目时,我收到控制台输出 2。它显示只有最后一项“item9”保存在相应的实体中(参见控制台输出 2)。

在遍历我的数组时,我必须更改哪些代码才能保存所有项目?

代码(swift 3):

        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        var calc_values = [CALC_VALUES]()
        let itemNames = [["item1", "item2", "item3", "item4", "item5"], ["item6", "item7", "item8", "item9"]]

//----------- save items -----------//          

        // flat multidimensional array to array
        let flatItemNames = itemNames.flatMap({ $0 })

        // save each item from flatItemNames to core data entity "CALC_VALUES" in attribute "calc_item":
            for itemName in flatItemNames {
                var newItem = NSEntityDescription.insertNewObject (forEntityName: "CALC_VALUES", into: context) as NSManagedObject
                newItem.setValue(itemName, forKey: "calc_item")
                (UIApplication.shared.delegate as! AppDelegate).saveContext()

                // Checkpoint 1:  Check newItem values
                print ("***This is newItem: *** \(newItem)")              
            }


//----------- load items -----------//  

        // Checkpoint 2: Check core data entry
        let fetchRequest: NSFetchRequest<CALC_VALUES> = CALC_VALUES.fetchRequest()
        do {
            if let results = try context.fetch(fetchRequest) as? [CALC_VALUES] {
                calc_values = results as! [CALC_VALUES]
            }
        } catch {print ("no results")}
        print ("***This is calc_values: *** \(calc_values)")

控制台输出检查点 1:

***This is newItem: *** <StartUpKit.CALC_VALUES: 0x6080000ad4a0> (entity: CALC_VALUES; id: 0x608000232a00 <x-coredata:///CALC_VALUES/t02F40B3E-95D3-4692-B630-2AEF16129A5F3> ; data: {
    "calc_item" = "item1";
    "calc_value" = 0;
})
***This is newItem: *** <StartUpKit.CALC_VALUES: 0x6000000ac1e0> (entity: CALC_VALUES; id: 0x600000235320 <x-coredata:///CALC_VALUES/t02F40B3E-95D3-4692-B630-2AEF16129A5F4> ; data: {
    "calc_item" = "item2";
    "calc_value" = 0;
})
***This is newItem: *** <StartUpKit.CALC_VALUES: 0x6000000ab880> (entity: CALC_VALUES; id: 0x600000236c80 <x-coredata:///CALC_VALUES/t02F40B3E-95D3-4692-B630-2AEF16129A5F5> ; data: {
    "calc_item" = "item3";
    "calc_value" = 0;
})

...

控制台输出检查点 2:

***This is calc_values: *** [<StartUpKit.CALC_VALUES: 0x6000000aac20> (entity: CALC_VALUES; id: 0xd000000001f00000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p124> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000aabc0> (entity: CALC_VALUES; id: 0xd000000001f40000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p125> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000aab60> (entity: CALC_VALUES; id: 0xd000000001f80000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p126> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000aab00> (entity: CALC_VALUES; id: 0xd000000001fc0000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p127> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000aaaa0> (entity: CALC_VALUES; id: 0xd000000002000000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p128> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000aaa40> (entity: CALC_VALUES; id: 0xd000000002040000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p129> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000aa9e0> (entity: CALC_VALUES; id: 0xd000000002080000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p130> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000aa980> (entity: CALC_VALUES; id: 0xd0000000020c0000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p131> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000aa680> (entity: CALC_VALUES; id: 0xd000000002100000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p132> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000aa5c0> (entity: CALC_VALUES; id: 0xd000000002140000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p133> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a9ea0> (entity: CALC_VALUES; id: 0xd000000002180000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p134> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a9d80> (entity: CALC_VALUES; id: 0xd0000000021c0000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p135> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a9de0> (entity: CALC_VALUES; id: 0xd000000002200000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p136> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a9cc0> (entity: CALC_VALUES; id: 0xd000000002240000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p137> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a99c0> (entity: CALC_VALUES; id: 0xd000000002280000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p138> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a9900> (entity: CALC_VALUES; id: 0xd0000000022c0000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p139> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a9240> (entity: CALC_VALUES; id: 0xd000000002300000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p140> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a9120> (entity: CALC_VALUES; id: 0xd000000002340000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p141> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a9180> (entity: CALC_VALUES; id: 0xd000000002380000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p142> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a9060> (entity: CALC_VALUES; id: 0xd0000000023c0000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p143> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a8d60> (entity: CALC_VALUES; id: 0xd000000002400000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p144> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a8ca0> (entity: CALC_VALUES; id: 0xd000000002440000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p145> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a6240> (entity: CALC_VALUES; id: 0xd000000002480000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p146> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a84c0> (entity: CALC_VALUES; id: 0xd0000000024c0000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p147> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000ac3c0> (entity: CALC_VALUES; id: 0xd000000002500000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p148> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000ac420> (entity: CALC_VALUES; id: 0xd000000002540000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p149> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000a8040> (entity: CALC_VALUES; id: 0xd000000002580000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p150> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000ac480> (entity: CALC_VALUES; id: 0xd0000000025c0000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p151> ; data: <fault>), <StartUpKit.CALC_VALUES: 0x6000000ab040> (entity: CALC_VALUES; id: 0xd000000002600000 <x-coredata://7687B389-1346-4C27-9B93-99B324FC28D2/CALC_VALUES/p152> ; data: {
    "calc_item" = "item9";
    "calc_value" = 0;
})]

【问题讨论】:

  • 出于调试原因,如果在循环更改行为后保存上下文,请尝试:try! context.save()
  • 你能展示你的实体 CALC_VALUES 类的样子吗?

标签: ios swift core-data


【解决方案1】:

乍一看,您似乎使用相同的键“calc_item”保存每个项目。因此,每次保存都会覆盖前一次。

【讨论】:

  • 嗯,是的,这是有道理的。除了newItem.setValue(itemName, forKey: "calc_item"),还有其他方法可以将 flatItemNames 中的字符串插入属性“calc_item”中吗?
  • (UIApplication.shared.delegate as! AppDelegate).saveContext() 保留在 for 循环之外。我更新了这个答案,但要完成同行评审。
【解决方案2】:

您必须将 (UIApplication.shared.delegate as! AppDelegate).saveContext() 保留在 for 循环之外。

下面是完整的代码。

    let itemNames = [["item1", "item2", "item3", "item4", "item5"], ["item6", "item7", "item8", "item9"]]
    let flatItemNames = itemNames.flatMap({ $0 })

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

    for itemName in flatItemNames {
        let managedContext = NSEntityDescription.insertNewObject(forEntityName: "CALC_VALUES", into: context)
        managedContext.setValue(itemName, forKey: "calc_item")
    }
    do {
        try context.save()
    } catch let error as NSError  {
        print("Error While Saving Data: \(error.userInfo)")
    }

要查看您的数据库更改,您可以使用SQLite Manager

下面是截图。

【讨论】:

  • 完美运行!感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
相关资源
最近更新 更多