Search code examples
ioscore-dataafincrementalstore

Performance issues with AFIncrementalStore


I'm experimenting with AFIncrementalStore, which is awesome, but I'm noticing that I am having some performance issues.

Specifically, I'm using it to bring down a bunch of facebook friends info from the facebook graph api, and I'm seeing some pretty slow clocktimes for save operations. For context, I'm loading in about 900 records. Instruments is telling me that the problem line is this:

 NSManagedObjectID *backingObjectID = [self objectIDForBackingObjectForEntity:entity withResourceIdentifier:resourceIdentifier];

which in turn calls this

[backingContext performBlockAndWait:^{
        backingObjectID = [[backingContext executeFetchRequest:fetchRequest error:&error] lastObject];
    }];

Has anyone had any experience with using AFIncremental store with larger data sets?

Somethign else I don't quite understand is why all this action is happening on the main thread when its all getting kicked off using a performBlockAndWait operation from a context with PrivateQueueConcurrencyType. Any help greatly appreciated!


Solution

  • Just a partial answer:

    performBlockAndWait: will execute the block on the private queue, but the calling thread will "appear to wait" until the block is finished. (note the "appear to wait", explained below).

    The queue is the underlaying mechanism to synchronize access to the shared resources. That ensures that shared resources can be accessed concurrently.

    Now, GCD can apply an optimization regarding selecting the thread used to drive the queue: if you dispatch synchronously GCD may choose to use the current thread which drives the private dedicated queue.

    Note: blocks enqueued on a particular queue can be executed on any thread. Nonetheless, the "execution context" is the queue - which determines synchronization.

    So, in other words performBlockAndWait: will appear as if it will be called synchronously. If the block will be executed on the same thread, this thread will not block. It just switches to the private queue when executing the block (and thereby guaranties shared access). This makes sense as the name of the message indicates: "..AndWait".