Strange behaviour of Core Data Query Generations

Since iOS10, Apple has introduced Core Data Query Generations to help developer in avoiding "CoreData could not fulfill a fault" error. However I found out that "CoreData could not fulfill a fault" error will still occurs even though I have pinned my managed object context to a query generation token.


I have created a sample app to demostrate how the error occurs even though query generation have been used.

(https://github.com/LeeKahSeng/QueryGenerationProblem)


Here's the core data model that I have setup for the sample app:

[Object1]<--->[Object2]<--->[Object3]<--->[Object4]<--->[Object5]<--->[Object6]


The sample app consist of 3 main components:


CoreDataModifier.swift

Singleton class that contain a private managed object context that in charge of deleting & updating Object2 in the core data store

CoreDataReader.swift

  • Class that fetch Object1 from the core data store and set query generation token to the managed object context.
  • CoreDataReader will keep a reference of Object1 from the fetch result.
  • "shouldDeleteInaccessibleFaults" have been set to false so that app will crash when "CoreData could not fulfill a fault" occurs.


ViewCnotroller.swift

Contain a "Loop" button that start a repeating timer. Every time the timer fire, the app will perform following step:

  1. Create some data & write to core data
  2. Create CoreDataReader
  3. Delete & update object created in step 1
  4. Print out data fetched from CoreDataReader to console


The strange behaviour:

After the timer started, it will fire for 28 times, on 29th time, the app will just freeze at line of code that try to print out fetched data. If we stop the app, build and run again, and start the timer again, the timer will fire for 27 times, on 28th time the app will crash with "CoreData could not fulfill a fault" error.


The above strange behaviour happen every time, thus I am not sure is this a bug in Core Data or it is just something that I have done wrongly.


This is really confusing, hope all the core data expert out there can have a look on the sample code and any explanation or suggestion is highly appreciated.


Thanks in advance.