Swift CoreData保存一对一关系

Swift CoreData saving a one-to-one relationship

在下面,我尝试使用 CoreData 保存一些分段控件。看起来很简单,但只保存了最近的控制索引。其余的由于某种原因被重置为 0。我没有选中每个属性的默认设置。

Quote 是我的主要实体,与 Worksheet 具有一对一关系,称为 worksheet

@IBAction func segmentPressed(_ sender: UISegmentedControl) {
   let worksheet = Worksheet(context: context)

   switch sender.tag {
   case 0:
      worksheet.irrigation = Int32(irrigationSegment.selectedSegmentIndex)
   case 1:
      worksheet.waste = Int32(wasteSegment.selectedSegmentIndex)
   case 2:
      worksheet.water = Int32(waterSegment.selectedSegmentIndex)
   default:
      break
   }

   if let quote = currentQuote as? Quote {
      quote.worksheet = worksheet
      appD.saveContext()
   }
 }

更新:我突然想到完全摆脱 switch 语句......现在它可以正确保存。但我仍然想知道为什么要重置这些值。也许 Int 属性在保存其上下文时自动设置为零但它没有值?似乎这就是默认值设置的作用。除了我的都没有检查。

每次执行 segmentPressed 函数时,都会创建一个新的 Worksheet 对象(所有属性都具有默认值)。您编写的代码(使用 switch 语句)仅设置一个属性的值,具体取决于已点击的分段控件。正如您在更新中注意到的那样,在删除 switch 语句后,您的代码会更新所有属性的值,并且一切看起来都很好。

但是,由于您每次都在创建一个新的 Worksheet 对象,因此您需要考虑旧对象的情况。由于关系是一对一的,当您将新的 Worksheet 分配给 currentQuote 时,旧的 Worksheet 对象的 link 将被删除 - 但旧的 Worksheet 对象仍然存在。因此,您正在构建一组 "orphaned" Worksheet 对象,这些对象没有 link 到任何 Quotes.

为避免这种情况,您应该检查 currentQuote 是否有现有的 Worksheet 对象。如果是,则更新该对象的适当属性;如果没有,创建一个新的 Worksheet,设置它的属性值(您可能想要设置所有属性值)并将关系设置为 currentQuote。像这样:

@IBAction func segmentPressed(_ sender: UISegmentedControl) {
    if let worksheet = currentQuote?.worksheet {
        switch sender.tag {
            case 0:
                worksheet.irrigation = Int32(irrigationSegment.selectedSegmentIndex)
            case 1:
                worksheet.waste = Int32(wasteSegment.selectedSegmentIndex)
            case 2:
                worksheet.water = Int32(waterSegment.selectedSegmentIndex)
            default:
                break
        }
        appD.saveContext()
    } else {
        if let quote = currentQuote as? Quote {
            let worksheet = Worksheet(context: context)
            worksheet.irrigation = Int32(irrigationSegment.selectedSegmentIndex)
            worksheet.waste = Int32(wasteSegment.selectedSegmentIndex)
            worksheet.water = Int32(waterSegment.selectedSegmentIndex)
            quote.worksheet = worksheet
            appD.saveContext()
        }
    }
}