Ich bin in einigen Schwierigkeiten mit Hintergrundthreads zum Aktualisieren von Daten in UIManagedDocument
/Core Data
. Insbesondere verwende ich eine NSFetchResultsController
, um Kartenanmerkungen auf der Grundlage von geocodierten Daten aus einem Hintergrund-Thread zu aktualisieren (nach dem Zusammenführen zurück in meine Haupt-MOC), aber die Karte wird nie aktualisiert aufgrund der Art und Weise Daten in seine Filialen und/oder zu seinen mehrere MOCs (Eltern und Kind). Wenn ich die App schließe und erneut öffne, werden die Annotationen aufgefüllt, so dass irgendwann ein Commit an den persistenten Speicher erfolgt, aber es ist mir unklar, wie man einen solchen Commit erzwingt, der somit die NSFetchResultsController
aktualisieren würde. Hier einige Code:Kerndaten: NSManagedObjectContext, NSFetchResultsController und UIManagedDocument
Der Hintergrund-Thread, der die MOC aktualisiert:
- (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);
}
Wenn diejenigen spart genannt werden, ergreife ich die Benachrichtigung über den Haupt-Thread (in meinem AppDelegate) wie folgt:
- (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));
}
Und ich habe meine geholt Ergebnisse Controller wie so gesetzt (das Prädikat stimmt, sind die Ergebnisse wie bei App Neustart erwartet, nachdem die Daten in den Laden begangen wurde):
-(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];
}
Irgendwelche Ideen, wie ich das entsprechende MOC aktualisieren kann, damit der abgerufene Ergebniscontroller sich wie gewünscht verhält?
Wer überhaupt? Völlig fest ..: / – Andrew