title: Core Data: use executeFetchRequest  in a loop
body: <p>Regarding one <a href="https://stackoverflow.com/a/12645804/359248">answer</a> in another post: is that use <code>executeFetchRequest</code> in a loop a bad practice? I saw that usage in Stanford CS193p project "<a href="http://www.stanford.edu/class/cs193p/cgi-bin/drupal/system/files/sample_code/Photomania_0.zip" rel="nofollow noreferrer">Photomania</a>" (click link to download project). The relevant code is below:</p>
  
  <p>The <code>[FlickrFetcher recentGeoreferencedPhotos]</code> is used to fetch photos from Flickr API, which happens in a background thread. But the loop that execute fetch request happens in main thread.</p>
  
  <pre><code>- (void)fetchFlickrDataIntoDocument:(UIManagedDocument *)document
  {
      dispatch_queue_t fetchQ = dispatch_queue_create("Flickr fetcher", NULL);
      dispatch_async(fetchQ, ^{    
          NSArray *photos = [FlickrFetcher recentGeoreferencedPhotos];
          // perform in the NSMOC's safe thread (main thread)
          [document.managedObjectContext performBlock:^{ 
              for (NSDictionary *flickrInfo in photos) {
                  // This is the method that will call executeFetchRequest
                  [Photo photoWithFlickrInfo:flickrInfo inManagedObjectContext:document.managedObjectContext];
              }  
              [document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
          }];
      });
      dispatch_release(fetchQ);
  }
  </code></pre>
  
  <p>Here is the factory method that first try to fetch objects from context (according to a pass-in object, which is fetched from flickr API). If result is nil, insert that object into context.</p>
  
  <pre><code>+ (Photo *)photoWithFlickrInfo:(NSDictionary *)flickrInfo
          inManagedObjectContext:(NSManagedObjectContext *)context
  {
      Photo *photo = nil;
  
      NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Photo"];
      request.predicate = [NSPredicate predicateWithFormat:@"unique = %@", [flickrInfo objectForKey:FLICKR_PHOTO_ID]];
      NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES];
      request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
  
      NSError *error = nil;
  
      NSArray *matches = [context executeFetchRequest:request error:&amp;error];
  
      if (!matches || ([matches count] &gt; 1)) {
          // handle error
      } else if ([matches count] == 0) {
          photo = [NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:context];
          photo.unique = [flickrInfo objectForKey:FLICKR_PHOTO_ID];
          photo.title = [flickrInfo objectForKey:FLICKR_PHOTO_TITLE]; 
          photo.subtitle = [flickrInfo valueForKeyPath:FLICKR_PHOTO_DESCRIPTION];
          photo.imageURL = [[FlickrFetcher urlForPhoto:flickrInfo format:FlickrPhotoFormatLarge] absoluteString];
          photo.whoTook = [Photographer photographerWithName:[flickrInfo objectForKey:FLICKR_PHOTO_OWNER] inManagedObjectContext:context];
      } else {
          photo = [matches lastObject];
      }
  
      return photo;
  }
  </code></pre>