1

I'm currently on a (very) big application developed by something else.

It's well developed and the code looks pretty good... Instead of the access to core data.

Indeed, each access to ManagedObjectContexts are made in several blocks, corresponding to several web services... in several threads.

And the documentation says it's bad. That's why sometimes, my app freeze on a Core Data access.

Yes, I know I should

Create a separate managed object context for each thread and share a single persistent store coordinator

as the doc says, but the code already exists and it's very huge and my client need a solution quickly (as usual).

So here's the question :

I've seen a [managedObjectContext lock] method. It seems to be some semaphore stuff. But the doc doesn't speak a lot about.

My webservices, in different threads are using the same instance of the managedObjectContext.

-What do you think about doing

[managedObjectContext lock]
// core data access
// core data access
// core data access
[managedObjectContext unlock]

In each of my web services blocks ?
-Will this resolve the freezes ?
-Is it a recommended way ?

Nobody told me about the lock & unlock methods, so I made an EDIT :

Because de freezes do not occurs everytime, I tried 3 cases :

  • Do not protect my data access

  • Use [managedObjectContext lock] unlock] methods

  • Use @synchronized(managedObjectContext) { ... }

In the first case, a freeze occured 3 times on 10 tests. In the 2nd and 3rd cases, no freeze at all.

So my second question :

What is the difference using lock/unlock and @synchronize( ) ?

Martin
  • 11,881
  • 6
  • 64
  • 110

2 Answers2

4

I had a similiar problem, on existing code I didn't work directly, with blocks performing fetch on a single managed object context, ended up on weird error, freezing, thread exiting etc.

I solved by adding a sinchronize on context:

NSBlockOperation *myBlock = [NSBlockOperation blockOperationWithBlock:^{

  // block operation

  @synchronized(managedObjectContext) {

    NSArray *result = [managedObjectContext performFetch:myFetch];

   // error management following

  }
}];

this is the quickest solution I found. I also tried to add some sort of locking condition but threads were messing up and deadlocking in some cases.

Leonardo
  • 9,607
  • 17
  • 49
  • 89
  • thanks for your answer, I will try it tomorrow. The problem is that it's hard to reproduce the freeze and see if the problem is resolved. – Martin Oct 04 '12 at 17:01
  • Try to see this question, is quite complete, and I used to decide between two options: http://stackoverflow.com/questions/1215330/how-does-synchronized-lock-unlock-in-objective-c/1215541#1215541 – Leonardo Oct 31 '12 at 15:57
1

I don't know what SDKs you need to run on, but if you can use iOS 5+ -performBlock: and -performBlockAndWait: may be just what you need.

Hope that helps.

Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117