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()
}
}
}
在下面,我尝试使用 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()
}
}
}