別の投稿の1つの回答について:executeFetchRequest
ループでの使用は悪い習慣ですか? スタンフォード CS193p プロジェクト " Photomania " (リンクをクリックしてプロジェクトをダウンロード) でその使用法を見ました。関連するコードは次のとおりです。
は[FlickrFetcher recentGeoreferencedPhotos]
、バックグラウンド スレッドで発生する Flickr API から写真を取得するために使用されます。ただし、フェッチ要求を実行するループはメインスレッドで発生します。
- (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);
}
これは、最初にコンテキストからオブジェクトをフェッチしようとするファクトリ メソッドです (パスイン オブジェクトに従って、flickr API からフェッチされます)。結果が nil の場合、そのオブジェクトをコンテキストに挿入します。
+ (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:&error];
if (!matches || ([matches count] > 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;
}