sqlite 永続ストアからバックグラウンド スレッドでコア データから単純なフェッチを実行しようとしています。
このメソッドは、オブジェクトを返す RESTful API 呼び出しからの応答です。このオブジェクトが見つかった場合、それを更新する必要があります。見つからない場合は、挿入します。
ただし、アプリを再起動するたびに初めて API が呼び出されると、フェッチが失敗し (SQL データベースにオブジェクトが表示されます)、新しいマネージド オブジェクトが挿入されます。ただし、この挿入によって新しいオブジェクトが作成されるわけではありません。オブジェクトはまだ 1 つしかありません。
API が 2 回目に呼び出されると、フェッチがオブジェクトを正常に検出し、すべてが正常に行われます。
したがって、述語は正しく、モデルにタイプミスはありません。
バックグラウンド メソッドの基本は次のとおりです。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
// Create a MOC for this background thread.
NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[backgroundContext setPersistentStoreCoordinator:((MyAppDelegate *)([UIApplication sharedApplication].delegate)).persistentStoreCoordinator];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mergeChanges:) name:NSManagedObjectContextDidSaveNotification object:backgroundContext];
// This is the returned value from the api call.
NSDictionary *responseDict = [completedOperation.responseString JSONValue];
NSString *venueName = [responseDict valueForKey:@"venueName"];
// VenueDescription is a managed object model.
VenueDescription *venueDesc = [[DatabaseManager sharedDatabaseManager] fetchVenueDescriptionForVenueName:venueName context:backgroundContext];
if (!venueDesc) { // venueDesc is nil the first time even though the object exists.
// This insert does NOT create a new object.
venueDesc = [NSEntityDescription insertNewObjectForEntityForName:@"VenueDescription" inManagedObjectContext:backgroundContext];
}
if (venueDesc) {
venueDesc.venueName = venueName;
/*.... code to update venueDesc from the dictionary....*/
[backgroundContext refreshObject:venueDesc mergeChanges:YES];
}
[[DatabaseManager sharedDatabaseManager] saveContext:backgroundContext];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:backgroundContext];
[backgroundContext release];
});
そして、これがフェッチメソッドです:
-(VenueDescription *)fetchVenueDescriptionForVenueName:(NSString *)venueName context:(NSManagedObjectContext *)context {
NSEntityDescription * entity = [NSEntityDescription entityForName:@"VenueDescription" inManagedObjectContext:context];
if (!entity) return nil;
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setResultType:NSManagedObjectResultType];
[fetchRequest setFetchLimit:1];
NSSortDescriptor *nameSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"venueName" ascending:YES];
NSArray *sortDescriptorArray = [NSArray arrayWithObject:nameSortDescriptor];
[nameSortDescriptor release];
[fetchRequest setSortDescriptors:sortDescriptorArray];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"venueName LIKE %@", venueName];
[fetchRequest setPredicate:predicate];
NSFetchedResultsController *controller = [[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil] autorelease];
NSError *error = nil;
[controller performFetch:&error];
if (error) NSLog(@"Error fetching Venue Descriptions: %@", error);
[fetchRequest release];
if ([controller.fetchedObjects count] == 0) return nil;
return [controller.fetchedObjects objectAtIndex:0];
}
私は何を間違っていますか?