У меня возникают проблемы с использованием фоновых потоков для обновления данных в UIManagedDocument
/Core Data
. В частности, я использую NSFetchResultsController
для обновления аннотаций карты на основе геокодированных данных из фонового потока (после объединения с моим основным MOC), но карта никогда не обновляется из-за того, как UIManagedDocument
передает данные в свои хранилища и/или в свои несколько MOC (родительский и дочерний). Если я закрою приложение и снова открою, аннотации будут заполнены, поэтому в какой-то момент происходит фиксация в постоянном хранилище, но мне неясно, как принудительно выполнить такую фиксацию, которая, таким образом, обновит файл 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, чтобы получить желаемый контроллер результатов?