title: Fetching array of NSManagedObjects by objectID returns empty array
body: <p>I'm trying to perform a fetch to retrieve managed objects from the context using an array of object IDs I gathered from a separate context. However, the fetch comes back with an empty array.</p>
  
  <p>From the "Retrieving Specific Objects" section of the "Core Data Programming Guide"
  <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdFetching.html#//apple_ref/doc/uid/TP40002484-SW1" rel="nofollow noreferrer">link</a>:</p>
  
  <blockquote>
    <p>If your application uses multiple contexts and you want to test whether an object has been deleted from a persistent store, you can create a fetch request with a predicate of the form self == %@. The object you pass in as the variable can be either a managed object or a managed object ID..."</p>
    
    <p>If you need to test for the existence of several objects, it is more efficient to use the IN operator than it is to execute multiple fetches for individual objects, for example:</p>
    
    <p>NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self IN %@",
                                                  arrayOfManagedObjectIDs];</p>
  </blockquote>
  
  <p>While this is talking about testing for object deletion, I presumed if the objects are not deleted then the results array is not empty, and will contain the actual NSManagedObjects. However, when I execute this code:</p>
  
  <pre><code>- (NSArray *)managedObjectsOfEntityName:(NSString *)entityName fromObjectIDs:(NSArray *)objectIDs managedObjectContext:(NSManagedObjectContext *)managedObjectContext
  {
      NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
      request.predicate = [NSPredicate predicateWithFormat:@"self IN %@", objectIDs];
  
      __autoreleasing NSError *error = nil;
  
      NSManagedObjectID *testID = objectIDs[0];
      NSManagedObject *obj = [managedObjectContext existingObjectWithID:testID error:&amp;error];
      if (!obj)
      {
          NSLog(@"Unable to perform fetch. Error: %@", error);
      }
  
      error = nil;
      NSArray *results = [managedObjectContext executeFetchRequest:request error:&amp;error];
      if (!results)
      {
          NSLog(@"Unable to perform fetch. Error: %@", error);
      }
  
      return results;
  }
  </code></pre>
  
  <p>The <code>results</code> array is non-nil and empty, while <code>obj</code> is properly populated.</p>
  
  <p>I've added the explicit call to <code>existingObjectWithID:</code> as a sanity check, and it comes back with the expected object, without error.</p>
  
  <p>Here's the debugger output for the pertinent variables:</p>
  
  <pre><code>(lldb) po entityName
  Foo
  
  (lldb) po objectIDs
  &lt;__NSArrayI 0x1170d4950&gt;(
  0xd0000000055c0082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p343&gt;,
  0xd000000008e80082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p570&gt;,
  0xd000000008840082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p545&gt;,
  0xd000000006040082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p385&gt;,
  0xd000000007740082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p477&gt;,
  0xd000000008280082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p522&gt;,
  0xd000000008e40082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p569&gt;
  )
  
  (lldb) po request
  &lt;NSFetchRequest: 0x10f338840&gt; (entity: Foo; predicate: (SELF IN {
  0xd0000000055c0082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p343&gt;,
  0xd000000008e80082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p570&gt;,
  0xd000000008840082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p545&gt;,
  0xd000000006040082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p385&gt;,
  0xd000000007740082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p477&gt;,
  0xd000000008280082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p522&gt;,
  0xd000000008e40082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p569&gt;});
  sortDescriptors: ((null)); type: NSManagedObjectResultType; )
  
  (lldb) po request.predicate
  SELF IN {
  0xd0000000055c0082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p343&gt;,
  0xd000000008e80082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p570&gt;,
  0xd000000008840082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p545&gt;,
  0xd000000006040082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p385&gt;,
  0xd000000007740082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p477&gt;,
  0xd000000008280082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p522&gt;,
  0xd000000008e40082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p569&gt;}
  
  (lldb) po testID
  0xd0000000055c0082 &lt;x-coredata://CEB1EDA5-7F7A-4342-85E5-6C2E261308CC/Foo/p343&gt;
  
  (lldb) p testID.isTemporaryID
  (bool) $7 = false
  
  (lldb) p obj
  (NSManagedObject *) $9 = 0x000000010f338630
  
  (lldb) po results
  &lt;__NSArrayI 0x10f205c70&gt;(
  
  )
  
  (lldb) po testID.entity
   nil
  </code></pre>
  
  <p>The <code>nil</code> <code>entity</code> on the <code>testID</code> is strange, but I'm not sure that's "bad."</p>
  
  <p>So, I'm obviously at a loss as to why the fetch is coming back empty. The entity name is correct, the fetch and predicate look good, and the object is in the context, but still zero results.</p>
  
  <p><strong>Additional Context:</strong></p>
  
  <p>Essentially, the larger picture is that I have a background operation which uses its own Managed Object Context (MOC) to perform some work. The results of that work are needed on the main queue, so I package up the objectIDs resulting from the work and pass those to the main queue. On the main queue I need the actual managed objects back, so I'm trying to fetch them, by objectID, from the main queue's MOC. I realize I can use <code>objectWithID:</code> or <code>existingObjectWithID:error:</code> or even <code>objectRegisteredForID:</code> on the MOC to get these objects, but each have their own special issues:</p>
  
  <ul>
  <li><code>objectWithID:</code> might return an object which is bogus if the object is not in the context, and if it is in the context it will return a fault.</li>
  <li><code>existingObjectWithID:error:</code> is great, since we'll get back <code>nil</code> (rather than a bogus object) but it too returns a fault.</li>
  <li><code>objectRegisteredForID:</code> will return <code>nil</code> if the object is not in the context already.</li>
  </ul>
  
  <p>So, if I use either <code>objectWithID:</code> or <code>existingObjectWithID:error:</code> in a loop to get a bunch of objects, that's potentially <code>n</code> trips to the persisted store to fault the objects, meaning performance is going to be potentially awful. If I use <code>objectRegisteredForID:</code> I might not get the object at all if it happens to not already be in the main queue's MOC.</p>
  
  <p>So, rather than try to iterate over the array, I expected a fetch request would limit the overhead of interacting with the persistance store and return all the objects I needed in one fell swoop.</p>
  
  <p><strong>Addition:</strong></p>
  
  <p>As an aside, the issue really feels like it has to do with the <code>@"self IN %@"</code> predicate, since I can remove that predicate and fetch all objects of <code>entityName</code> without issue. I have also tried <code>@"objectID IN %@"</code> as the predicate with the same (zero) results.</p>