title: Core Data, caching NSManagedObjects in NSMutableDictionary, Problems
body: <p>I am writing a dictionary application, and i am trying to import raw data from strings, one string per word. Amongst other things, the raw input strings contain the names of the parts of speech the corresponding word belongs to. In my datamodel I have a separate entity for <code>Word</code>s and <code>PartOfSpeech</code>, and i want to create one entity of the type <code>PartOfSpeech</code> for each unique part of speech there may be in the input strings, and establish the relationships from the <code>Word</code>s to the relevant pars of speech. The <code>PartOfSpeech</code> entity has just one Atribute, <code>name</code>, and one-to-many relationship to the <code>Word</code>: 
  <img src="https://i.stack.imgur.com/s7zJl.png" alt="enter image description here"></p>
  
  <p>My first implementation of getting unique <code>PartOfSpeech</code> entities involved caching them in a mutable array and filtering it each time with a predicate. It worked, but it was slow. I decided to speed it up a bit by caching the PartsOfSpeech in an NSDictionary, and now when i try and save the datastore after the import, i get the error "Cannot save objects with references outside of their own stores.". It looks like the problem is in the dictionary, but how can i solve it?</p>
  
  <p>Here is the code that worked:
  (in both sniplets <code>managedObjectContext</code> is an ivar, and <code>processStringsInBackground:</code> method runs on a background thread using <code>performSelectorInBackground:withObject:</code> method)</p>
  
  <pre><code>- (void) processStringsInBackground:(NSFetchRequest *)wordStringsReq {
      NSError *err = NULL;    
      NSFetchRequest *req = [[NSFetchRequest alloc] init];
      [req setEntity:[NSEntityDescription entityForName:@"PartOfSpeech" inManagedObjectContext:managedObjectContext]];
      err = NULL;
      NSMutableArray *selectedPartsOfSpeech = [[managedObjectContext executeFetchRequest:req error:&amp;err] mutableCopy];
      NSPredicate *p = [NSPredicate predicateWithFormat:@"name like[c] $name"];
      //  NSPredicate *formNamePredicate = [NSPredicate predicateWithFormat:&lt;#(NSString *)predicateFormat#&gt;]
  ...
      for (int i = 0; i &lt; count; i++){
  ...     
          currentPos = [self uniqueEntityWithName:@"PartOfSpeech" usingMutableArray:selectedPartsOfSpeech predicate:p andDictionary:[NSDictionary dictionaryWithObject:partOfSpeech forKey:@"name"]];
  ...
      }
  }
  
  - (NSManagedObject *) uniqueEntityWithName:(NSString *) entityName usingMutableArray:(NSMutableArray *)objects predicate:(NSPredicate *)aPredicate andDictionary:(NSDictionary *) params {
      NSPredicate *p = [aPredicate predicateWithSubstitutionVariables:params];
      NSArray *filteredArray = [objects filteredArrayUsingPredicate:p];
      if ([filteredArray count] &gt; 0) {
          return [filteredArray objectAtIndex:0];
      }
      NSManagedObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:managedObjectContext];
      NSArray *dicKeys = [params allKeys];
      for (NSString *key in dicKeys) {
          [newObject willChangeValueForKey:key];
          [newObject setPrimitiveValue:[params valueForKey:key] forKey:key];
          [newObject didChangeValueForKey:key];
      }
      [objects addObject:newObject];
      return newObject;
  }
  </code></pre>
  
  <p>And here is the same, but with caching using NSMutableDictionary, which fails to save afterwards:</p>
  
  <pre><code>- (void) processStringsInBackground:(NSFetchRequest *)wordStringsReq {
      NSError *err = NULL;    
      [req setEntity:[NSEntityDescription entityForName:@"PartOfSpeech" inManagedObjectContext:managedObjectContext]];
      NSArray *selectedPartsOfSpeech = [managedObjectContext executeFetchRequest:req error:&amp;err];
      NSMutableDictionary *partsOfSpeechChache = [[NSMutableDictionary alloc] init];
      for (PartOfSpeech *pos in selectedPartsOfSpeech) {
          [partsOfSpeechChache setObject:pos forKey:pos.name];
      }
  ...
      for (int i = 0; i &lt; count; i++){
  ...     
          currentPos = [self uniqueEntity:@"PartOfSpeech" withName:partOfSpeech usingDictionary:partsOfSpeechChache];
  ...
      }
  }
  
  - (NSManagedObject *)uniqueEntity:(NSString *) entityName withName:(NSString *) name usingDictionary:(NSMutableDictionary *) dic {
      NSManagedObject *pos = [dic objectForKey:name];
      if (pos != nil) {
          return pos;
      }
      NSManagedObject *newPos = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:managedObjectContext];
      [newPos willChangeValueForKey:@"name"];
      [newPos setPrimitiveValue:name forKey:@"name"];
      [newPos didChangeValueForKey:@"name"];
  
      [dic setObject:newPos forKey:name];
      return newPos;
  }
  </code></pre>
  
  <p>Could you help me to find the problem?</p>
  
  <p>Best regards, 
  Timofey.</p>