UIManagedDocument
バックグラウンド スレッドを使用して/内のデータを更新する際に問題が発生していますCore Data
。具体的にはNSFetchResultsController
、バックグラウンド スレッドからジオコーディングされたデータに基づいてマップ アノテーションを更新するために を使用していますが (メインの MOC にマージして戻した後)、マップは更新されませんUIManagedDocument
。 (親子)。アプリを閉じて再度開くと、注釈が入力されるため、ある時点で永続ストアへのコミットが発生しますが、そのようなコミットを強制してNSFetchResultsController
. ここにいくつかのコードがあります:
MOC を更新するバックグラウンド スレッド:
- (void) populateGPSCoordsInClubsInContext: (NSManagedObjectContext *) mainCtx
{
dispatch_queue_t MapFetchQ = dispatch_queue_create("Google Map Data Fetcher", NULL);
dispatch_async(MapFetchQ, ^{
NSManagedObjectContext * ctxThread = [[NSManagedObjectContext alloc] init];
[ctxThread setPersistentStoreCoordinator:mainCtx.persistentStoreCoordinator];
NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"Club"];
request.predicate = [NSPredicate predicateWithFormat:@"inRegion.name=%@", self.name];
NSError *error = nil;
NSArray * clubs = [ctxThread executeFetchRequest:request error:&error];
NSLog(@"[%@] Fetching map data. Club count is %d", self.name, [clubs count]);
int delayCounter = 0;
for(Club * club in clubs)
{
if(![club.hasCoord boolValue] && club != nil)
{
delayCounter++; // to deal with google maps api's DoS protection
[club setLongitudeAndLattitudeFromGoogle];
NSError * error;
if(![ctx save:&error])
NSLog(@"[%@] Problem saving region to database.", self.name);
}
if(delayCounter == 8)
{
[NSThread sleepForTimeInterval:(NSTimeInterval)2.0];
delayCounter = 0;
}
}
});
dispatch_release(MapFetchQ);
}
これらの保存が呼び出されると、次のようにメイン スレッド (アプリ デリゲート内) で通知を取得します。
- (void) contextDidSave: (NSNotification *) notification
{
NSManagedObjectContext * ctx = [self.clubsDB managedObjectContext];
[ctx mergeChangesFromContextDidSaveNotification:notification];
NSArray * updates = [[notification.object updatedObjects] allObjects];
for(Club * club in updates) // This never fires because updates never has objects
{
NSLog(@"*********** %@", club.name);
}
NSLog(@"[%@] %@", [self class], NSStringFromSelector(_cmd));
}
そして、フェッチした結果コントローラーを次のように設定しました (述語は正しいです。データがストアにコミットされた後にアプリを再起動すると、結果は期待どおりになります)。
-(void) setupFRC
{
NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"Club"];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];
request.predicate = [NSPredicate predicateWithFormat:@"inRegion.name=%@ AND hasCoord=%@",[self.clubsDB regionTitleAsString], [NSNumber numberWithBool:YES]]; // Follow the relationshop and only display clubs from THIS region.
//request.predicate = [NSPredicate predicateWithFormat:@"inRegion.name=%@",[self.clubsDB regionTitleAsString]];
self.debug = YES;
self.fetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.clubsDB.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
}
適切なMOCを更新して、フェッチされた結果コントローラーを希望どおりに動作させる方法についてのアイデアはありますか?