Swift CoreData 保存一对一的关系

Posted

技术标签:

【中文标题】Swift CoreData 保存一对一的关系【英文标题】:Swift CoreData saving a one-to-one relationship 【发布时间】:2019-02-12 18:07:22 【问题描述】:

下面我有一些分段控件,我正在尝试使用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 属性在保存其上下文但没有值时自动设置为零?似乎这就是默认值设置的作用。除了我的都没有检查。

【问题讨论】:

【参考方案1】:

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

但是,由于您每次都在创建一个新的 Worksheet 对象,因此您需要考虑旧对象的情况。由于关系是一对一的,当您将新的Worksheet 分配给currentQuote 时,旧Worksheet 对象的链接将被删除-但旧Worksheet 对象仍然存在。因此,您正在构建一组“孤立”Worksheet 对象,这些对象与任何 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()
        
    

【讨论】:

这是一个很好的解释,谢谢。我还有一些文本框和一个文本视图,所以现在我测试 ViewDidLoad 中的工作表是否为零,并在必要时调用初始化方法。

以上是关于Swift CoreData 保存一对一的关系的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Swift 在 CoreData 中访问一对多关系

一对多关系CoreData Swift

Swift 2:使用一对多条件保存 coredata

保存一对多关系CoreData

一对多关系设置器

与 coredata 的一对多关系