Ok - also habe ich alles herausgefunden.
Das Modell ist wie in: Marcus Zarra des http://martiancraft.com/blog/2015/03/core-data-stack/ Die privateMOC an der Wurzel ist, das für eine bessere Leistung ermöglicht und auch auf diese Weise aus anderen Gründen erforderlich ist. Ich benutze nur 2 MOCs: das private root one und das child one, das ein Haupt-Thread ist.
dies Dann lesen: Grundsätzlich erklärt er, wie Core Data-Benachrichtigungen Griffe usw. http://benedictcohen.co.uk/blog/archives/308
THEN - das letzte, was ich tun musste: alle ObjectIDs im Programm stellen Sie sicher, echte Dauer diejenigen sind.
- (id)insertNewObjectForEntityName:(NSString *)entityName inManagedObjectContext:(NSManagedObjectContext *)context {
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context];
// Make sure all inserted objects have a permanent ID.
// THIS IS VITAL. Without getting the permanentIDs, changes that come in from the web will not propogate to the child mainQ MOC and the UI will not update.
// Tested to be performant.
//NSLog(@"testing this - object.objectID is a temp now I think: %@ isTemp:%d", object.objectID, (int) [object.objectID isTemporaryID]);
// http://stackoverflow.com/questions/11990279/core-data-do-child-contexts-ever-get-permanent-objectids-for-newly-inserted-obj
NSError* error = nil;
[context obtainPermanentIDsForObjects:@[object] error:&error];
if (error || [object.objectID isTemporaryID])
NSLog(@"obtainPermanentIDsForObjects is NOT WORkING - FIX: a new %@ isTemp: %d !!", entityName, (int) [object.objectID isTemporaryID]);
return object;
}
Auch musste ich laut Benedicts Artikel - für Änderungen im Stamm privaten MOC Eltern hören
/// . http://benedictcohen.co.uk/blog/archives/308 good info !
/// I need this firing as sometimes objects change and the save notification below is not enough to make sure the UI updates.
- (void)privateQueueObjectContextDidChangeNotification:(NSNotification *)notification {
NSManagedObjectContext *changedContext = notification.object;
NSManagedObjectContext *childContext = self.mainQueueObjectContext;
BOOL isParentContext = childContext.parentContext == changedContext;
if (!isParentContext) return;
//Collect the objectIDs of the objects that changed
__block NSMutableSet *objectIDs = [NSMutableSet set];
[changedContext performBlockAndWait:^{
NSDictionary *userInfo = notification.userInfo;
for (NSManagedObject *changedObject in userInfo[NSUpdatedObjectsKey]) {
[objectIDs addObject:changedObject.objectID];
}
for (NSManagedObject *changedObject in userInfo[NSInsertedObjectsKey]) {
[objectIDs addObject:changedObject.objectID];
}
for (NSManagedObject *changedObject in userInfo[NSDeletedObjectsKey]) {
[objectIDs addObject:changedObject.objectID];
}
}];
//Refresh the changed objects
[childContext performBlock:^{
for (NSManagedObjectID *objectID in objectIDs) {
NSManagedObject *object = [childContext existingObjectWithID:objectID error:nil];
if (object) {
[childContext refreshObject:object mergeChanges:YES];
//NSLog(@"refreshing %@", [object description]);
}
}
}];
}
- (void)privateQueueObjectContextDidSaveNotification:(NSNotification *)notification {
//NSLog(@"private Q MOC has saved");
[self.mainQueueObjectContext performBlock:^{
[self.mainQueueObjectContext mergeChangesFromContextDidSaveNotification:notification];
// I had UI update problems which I fixed with mergeChangesFromContextDidSaveNotification along with obtainPermanentIDsForObjects: in the insertEntity call.
}];
}
/// When the MainMOC saves - the user has changed data.
/// We save up into the privateQ as well at this point.
- (void)mainQueueObjectContextDidSaveNotification:(NSNotification *)notification {
NSLog(@"main Q MOC has saved - UI level only changes only please");
[self.privateQueueObjectContext performBlock:^{
NSError* error = nil;
if (self.privateQueueObjectContext.hasChanges) {
[self.privateQueueObjectContext save:&error];
if (error)
{
NSLog(@"Save up error - the actual datastore was not updated : %@", error);
}
} else {
//NSLog(@"No need to save");
}
}];
}
Keine seiner andersrum . Der privateMOC ist die Wurzel, dies ermöglicht eine bessere Leistung und wird auch aus anderen Gründen benötigt. Ich benutze nur 2 MOCs das private root one und das Kind eines, das ein Hauptthread ist. –
dann folgen Sie nicht der Anleitung der Seite, auf die Sie verlinken ...Wenn Sie Ihren Ansatz verwenden, müssen Sie die Änderungen nach dem Speichern in den Hauptkontext zusammenführen. Das passiert nicht automatisch. – Wain
Ich sehe - Marcus Zarras Seite hat ein privateQ im Wurzelverzeichnis. Er hat dann eine mainThreadQ darunter. Das mache ich also. Aber rät mehrere Privatpersonen unterhalb dieser Hauptleitung, was zu echten Leistungsproblemen in einem Setup führt, bei dem die meisten der Daten, die in das System kommen, von Nicht-Benutzereingaben stammen. –