0

I am currently using a method where I run a fetch request in the background to obtain object IDs, and then instantiating them with -existingObjectWithID:error:.

The problem is that these objects have to-many relation to a large number of objects. And the UI freezes for a while when these objects are accessed. (They are accessed all at once.)

I am guessing that the related objects are faults. I am trying to figure out a way to preload them in the background. Is there a solution to this problem?

Barum Rho
  • 2,743
  • 1
  • 20
  • 21
  • Core data by itself is not thread safe. Possible dupe: http://stackoverflow.com/questions/1733117/fetching-core-data-in-the-background – CodaFi Mar 24 '12 at 22:03
  • Yes, I have a separate `NSManagedObjectContext` for the background thread. That is why I am using `-existingObjectWithID:error:`. – Barum Rho Mar 24 '12 at 22:33

3 Answers3

0

Core data is not thread safe. So for background thread you should have separate managed context. Typically core data don't take lots time to load. But if you are storing blobs (like image data) it can hit the performance. You should you NSFetchRequestController with page size you want to set. It much faster So you probably wont need to worry about about background fetching

Atif Khan
  • 125
  • 1
  • 7
  • This is from a while ago, but I was using thread confinement correctly, which is why I was using `-existingObjectWithID:error:`. I was wondering if there were a way to fetch relationships in the background as well. I moved to using a background thread, because the query was already taking too long. – Barum Rho Jun 13 '13 at 18:16
  • @BarumRho i believe existingObjectWithID:error doesn't guaranty thread safe fetching. – Atif Khan Jun 16 '13 at 08:53
  • @BarumRho I would suggest instead of recreating managed object, just pass the array of ManagedObject ID's. And use these id's in table cell or other place to fetch object from main thread managed context. That would be efficient as vary few records will be visible at one time – Atif Khan Jun 16 '13 at 08:57
  • That's exactly what I was doing already. The problem was that I was still seeing a pause in UI while all the relationships were getting fetched. – Barum Rho Jun 16 '13 at 21:47
  • @BarumRho how are you creating managedContext (i mean which initializer, and in which thread did you call that) – Atif Khan Jun 17 '13 at 09:08
  • I don't have the source code handy, but I was using two different contexts: one for main thread, one for a background thread. Anyway, I didn't have any issues with threading. The issue was that fetching relationships was too expensive. – Barum Rho Jun 17 '13 at 18:55
0

Try the setRelationshipKeyPathsForPrefetching: method on NSFetchRequest. Pass in an array of keys that represent relationships that should be fetched rather than faulted.

Amy Worrall
  • 16,250
  • 3
  • 42
  • 65
  • That will not achieve what I want, since when I fetch in the background thread, I am setting `resultType` to `NSManagedObjectIDResultType`. I think `relationshipKeyPathsForPrefetching` gets ignored in this case. – Barum Rho Mar 25 '12 at 00:34
0

Do you know for sure that it is your main thread that is causing the slowdown (sure sounds like it) - I'd use Instruments and "Time Profiler" to be sure, and there is also a way to turn on SQL debugging/timing too.

If it is your main thread, there are fantastic WWDC videos (take a look at 2010 too, not just 2011) on how to optimize Core Data.

Community
  • 1
  • 1
Scott Corscadden
  • 2,831
  • 1
  • 25
  • 43