title: NSManagedObjectContext lock
body: <p>I'm writing a multi-threaded application using Core Data.</p>
  
  <p>I'm under the impression that <code>- [NSManagedObjectContext lock]</code> does not work as a standard lock. As a proof of concept here is a sample built after the Xcode 3 "Command-line tool" template, "Core Data" flavor:</p>
  
  <pre class="lang-objective-c prettyprint-override"><code>int main (int argc, const char * argv[])
  {
    objc_startCollectorThread();
  
    NSManagedObjectContext *context = managedObjectContext();
  
    [context lock];
    [context lock];
  
    NSLog(@"hello world! (context=%@)", context);
  
    [context unlock];
    [context unlock];
  
    return 0;
  }
  </code></pre>
  
  <p>That should result in a deadlock, instead when running under Mac OS X 10.6.8 or 10.7.4, I've got this log:</p>
  
  <pre><code>2012-07-18 16:53:40.206 test[20004:a0b] hello world! (context=&lt;NSManagedObjectContext: 0x20000df40&gt;)
  </code></pre>
  
  <p>Can anybody tell me what is happening?</p>
  
  <p>(if I use instances of NSLock instead of the context, the deadlock happens as expected)</p>
  
  <hr>
  
  <p>here is an excerpt from <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/NSManagedObjectContext.html#//apple_ref/occ/instm/NSManagedObjectContext/lock" rel="nofollow">Apple Documentation about NSManagedObjectContext lock</a></p>
  
  <h2>lock</h2>
  
  <p>Attempts to acquire a lock on the receiver.</p>
  
  <p><code>- (void)lock</code></p>
  
  <p>Discussion</p>
  
  <p>This method blocks a thread’s execution until the lock can be acquired. An application protects a critical section of code by requiring a thread to acquire a lock before executing the code. Once the critical section is past, the thread relinquishes the lock by invoking unlock.</p>
  
  <p>Sending this message to a managed object context helps the framework to understand the scope of a transaction in a multi-threaded environment. It is preferable to use the NSManagedObjectContext’s implementation of NSLocking instead using of a separate mutex object.</p>
  
  <p>If you lock (or successfully tryLock) a managed object context, the thread in which the lock call is made must have a retain until it invokes unlock. If you do not properly retain a context in a multi-threaded environment, this will result in deadlock.</p>
  
  <p>Availability
  Available in Mac OS X v10.4 and later.</p>