Database Reference
In-Depth Information
3. The code saves the main context via
saveContext
, defined in
CoreDataStack.swift
, persisting any edits to disk.
4. Finally, the code dismisses the
JournalEntryViewController
using animation.
Note:
If a managed object context is of type
MainQueueConcurrencyType
, you
don't have to wrap code in
performBlock
, but it doesn't hurt to use it. If you
don't know what type the context will be, as is the case in
didFinishViewController(_:didSave:)
, it's safest to use
performBlock
so it will
work with both parent and child contexts.
There's a problem with the above implementation—have you spotted it?
When the app adds a new journal entry, it creates a new object and adds it to the
managed object context. If the user taps the Cancel button, the app doesn't save
the context, but the new object is still present. If the user then adds and saves
another
entry, the cancelled object is still present! You won't see it in the UI unless
you've got the patience to scroll all the way to the end, but it will show up at the
bottom of the CSV export.
You could solve this problem by deleting the object when the user cancels the view
controller. But what if the changes made were more complex, or involved multiple
objects, or you had to alter properties of an object as part of the editing workflow?
Canceling could soon get very complicated. It's much easier to use a temporary
child context.
Using child contexts for sets of edits
Now that you know how the app currently edits and creates
JournalEntry
entities,
you'll modify the implementation to use a child managed object context as a
temporary scratch pad.
It's easy to do—you simply need to modify the segues. Open
JournalListViewController.swift
and find the following code for
“SegueListToDetail”
in
prepareForSegue
:
detailViewController.
journalEntry
= surfJournalEntry
detailViewController.
context
=
surfJournalEntry.
managedObjectContext
detailViewController.
delegate
=
self
Now replace that code with the following:
// 1
let
childContext =
NSManagedObjectContext
(
concurrencyType: .
MainQueueConcurrencyType
)
childContext.
parentContext
=
coreDataStack
.
context