Sunday, April 2, 2023
HomeiOS Developmentios - Cannot save objects with references outside their own stores, background...

ios – Cannot save objects with references outside their own stores, background and main context issue


I have a core data store. What I want is to perform saves in a background context, and fetches on the main context. So I have the following setup of CoreDataStack that handles the saving/fetching in the core data:

class CoreDataStack {
  static let modelName = "Model"

  static let managedObject: NSManagedObjectModel = {
    guard let modelUrl = Bundle.module.url(
      forResource: "Model",
      withExtension: "momd"
    ) else {
      return .init()
    return NSManagedObjectModel(contentsOf: modelUrl) ?? .init()

  lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(
      name: Self.modelName,
      managedObjectModel: Self.managedObject

    let dispatchGroup = DispatchGroup()

    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
      if let error = error as NSError? {
        print("Unresolved error \(error), \(error.userInfo)")


    return container

  lazy var backgroundContext: NSManagedObjectContext = {
    let context = persistentContainer.newBackgroundContext()
    context.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
    return context

  lazy var mainContext: NSManagedObjectContext = {
    let mainContext = persistentContainer.viewContext
    mainContext.automaticallyMergesChangesFromParent = true
    mainContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
    return mainContext

  func fetch<Item: NSManagedObject>(
    _ request: NSFetchRequest<Item>
  ) -> [Item] {
    do {
      let items = try self.mainContext.fetch(request)
      return items
    } catch let error as NSError {
      print("Unresolved error \(error), \(error.userInfo)")
      return []

  func saveContext() {
    backgroundContext.perform {
      do {
      } catch let error as NSError {
        print("Unresolved error \(error), \(error.userInfo)")

I have an NSManagedObject called ManagedBar. This contains a data property which is an NSSOrderedSet of another NSManagedObject called ManagedFoo.

I have a function saveFoo(_:) which creates a ManagedFoo on the background context, requests a ManagedBar in the foreground context, then if that ManagedBar exists, adds it to the ManagedFoo to data. Then the background context is saved:

func saveFoo(_ Foo: Foo) {
  let managedFoo = ManagedFoo(
    context: coreDataStack.backgroundContext,

  let request = ManagedBar.fetchRequest()
  request.predicate = NSPredicate(format: "name == %@",

  if let bar = coreDataStack.fetch(request).first {
  } else {
    let event = ManagedBar(
      context: self.coreDataStack.backgroundContext,

I also have a function to retrieve all the name properties of ManagedBar which fetches them all from the main context:

func getAllBarNames() -> [String] {
  let fetchRequest = ManagedEvent.fetchRequest()
  let eventData = coreDataStack.fetch(fetchRequest)
  let names = { $ }
  return names

Then, when I run the following code, it works most of the time but sometimes fails:

func testGetAllEventNames() {
  let foo1 = Foo()

  let foo2 = Foo()

  let names = getAllBarNames()

This sometimes works fine, but other times fails for one of two reasons:

  1. Cannot save objects with references outside their own stores.
  2. Collection <__NSCFSet: 0x6000031407b0> was mutated while being enumerated. (this occurs on the second saveFoo)

Other times, names doesn’t contain all the names that I’ve saved. These errors happen even if I run this code in a unit test and wait for the NSManagedObjectContextDidSave notification before calling getAllBarNames()

This must be caused by some background/main context issue but not entirely sure what. Does anyone know what’s going wrong here?


Source link



Please enter your comment!
Please enter your name here

Most Popular

Recent Comments