Reputation: 1945
Below I have a handful of segmented controls that I'm trying to save using CoreData
. It seems pretty straight forward, but only the most recent control index is being saved. The rest are being reset to 0 for some reason. I have unchecked the default setting for each attribute.
Quote
is my main entity and has a one-to-one relationship with Worksheet
called 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()
}
}
UPDATE: It occurred to me to get rid of the switch statement altogether...and now it saves properly. But I'd still like to know why the values were being reset. Maybe an Int attribute automatically gets set to zero when its context is saved but it has no value? It seems like that's what the default value setting would do. Except mine were all unchecked.
Upvotes: 1
Views: 623
Reputation: 21536
Every time the segmentPressed
function is executed, a new Worksheet
object is created (with default values for all its attributes). Your code as written (with the switch
statement) sets the value for only one attribute, depending on which segmented control has been tapped. As you note with your update, after removing the switch statement, your code updates the values for all the attributes, and all appears good.
However, since you are creating a new Worksheet
object each time, you need to consider what's happening to the old ones. As the relationship is one-one, when you assign your new Worksheet
to the currentQuote
, the link to the old Worksheet
object is removed - but the old Worksheet
object remains. You are therefore building up a group of "orphaned" Worksheet
objects which have no link to any Quotes
.
To avoid this, you should check whether the currentQuote
has an existing Worksheet
object. If so, update the appropriate attribute of that object; if not, create a new Worksheet
, set its attribute values (you might want to set all of them) and set the relationship to the currentQuote
. Something like this:
@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()
}
}
}
Upvotes: 1