0

I have a weird issue with CoreData. When I first load the data everything seems to work ok, but after saving the data all subsequent fetch requests stop working (or rather return empty).

I copied the CoreDataStack from this project which is an example project by udacity. It contains a saving helper function.

func save() {
        context.performAndWait() {
            if self.context.hasChanges {
                do {
                    try self.context.save()
                } catch {
                    fatalError("Error while saving main context: \(error)")
                }
                // now we save in the background
                self.persistingContext.perform() {
                    do {
                        try self.persistingContext.save()
                    } catch {
                        fatalError("Error while saving persisting context: \(error)")
                    }
                }
            }
        }
    }

Inside of my view controller I am able to run fetch requests normaly for different predicates using code like the one below.

fetchedResultsController?.fetchRequest.predicate = NSPredicate(format: "fromDatetime >= %@ AND fromDatetime < %@", argumentArray: [selectionTime, selectionTime + 3600_000])
fetchedResultsController?.managedObjectContext.refreshAllObjects()
let m = fetchedResultsController?.fetchedObjects as! [Measurement]
print("number of elements in m: \(m.count)")

After saving the data with a test button.

@IBAction func testAction(_ sender: Any) {
    // test action
    print("test clicked")
    let delegate = UIApplication.shared.delegate as! AppDelegate
    let stack = delegate.stack
    stack.save()
}

all subsequent fetch requests are empty. I also created another ViewController which implements the UITableViewController, containing all the data stored on the device. If I open it, the data is still displayed correctly there, even after the save. What could cause this sort of behavior?

Lukasz
  • 2,257
  • 3
  • 26
  • 44

1 Answers1

0

This is likely the result of a deadlock caused by performAndWait() that blocks the UI thread because of it operating in different queues and not all sharing the same public queue. to resolve this, set up an instances variable for the managedObjectContext and always reference this context to avoid blocking access to your managedObjectContext.

 lazy var mainContext: NSManagedObjectContext = {
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
return appDelegate!.managedObjectContext
 }

Check out this other question that addresses a similar issue.

stonybrooklyn
  • 122
  • 2
  • 10