Key data: The union of children added to the background context is funky

Background

  • Multithreaded Core Data p>

  • NSTreeControllerand NSOutlineViewwith bindings

  • Creates child objects in NSOperation in the background context

  • Combines into the main context using mergeChangesFromContextDidSaveNotification

Data model

Problem

  • If I complete 20 operations of creating children, as soon as the mergers are completed, I see only about 10-15 children in the outline representation.

  • If I set the maximum parallel operations to 1, it works fine and I see 20 children.

Question

Am I trying to do something impossible? I see how master data can successfully merge. Or is there a problem with my code?

the code

JGGroupController

 -(id)init {
     self = [super init];
     queue = [[NSOperationQueue alloc] init];
     [queue setMaxConcurrentOperationCount:10]; // If this is 1, it works like a dream. Anything higher and it bombs.
     return self;
 }

 -(IBAction)addTrainingEntryChild:(id)sender {
     moc  = [[NSApp delegate] managedObjectContext];
     JGTrainingBase *groupToAddTo = [[tree selectedObjects] objectAtIndex:0];
     for (NSUInteger i = 0; i < 20; i++) {
         JGAddChildrenObjectOperation    *addOperation = [[JGAddChildrenObjectOperation alloc] init]; 
         [addOperation addChildObjectToGroup:[groupToAddTo objectID]];
         [queue addOperation:addOperation];
     }
 }

JGAddChildrenObjectOperation - subclass of NSOperation

 -(id)addChildObjectToGroup:(NSManagedObjectID *)groupToAddToID_ {
     groupToAddToObjectID = groupToAddToID_;
     return self;
 }

 -(void)main {
     [self startOperation];
     JGTrainingBase *groupToAddTo    = (JGTrainingBase *)[imoc objectWithID:groupToAddToObjectID];
     JGTrainingBase *entryChildToAdd = [JGTrainingBase insertInManagedObjectContext:imoc];
     [groupToAddTo addChildren:[NSSet setWithObject:entryChildToAdd]];
     [imoc save];
 [self cleanup];
     [self finishOperation];
 }

 -(void)mergeChanges:(NSNotification *)notification {
     NSManagedObjectContext *mainContext = [[NSApp delegate] managedObjectContext];
     [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                                   withObject:notification
                                waitUntilDone:YES];  
 }


 -(void)startOperation {
            // Omitted - Manage isExecuting, isPaused, isFinished etc flags

     imoc = [[NSManagedObjectContext alloc] init];
     [imoc setPersistentStoreCoordinator:[[NSApp delegate] persistentStoreCoordinator]];
     [imoc setUndoManager:nil];
     [imoc setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
     [imoc setStalenessInterval:0];

     [[NSNotificationCenter defaultCenter] addObserver:self
                                              selector:@selector(mergeChanges:) 
                                                  name:NSManagedObjectContextDidSaveNotification 
                                                object:imoc];
 }

 -(void)finishOperation {
            // Omitted - Manage isExecuting, isPaused, isFinished etc flags
 }
+3
1

"" . :

2 , O: F O: G, F G 1, G: 1 [A, B, C, D, E ].

O: F O: G, G: 1.

O: F G: 1 [A, B, C, D, E, F]. O: G G: 2 [A, B, C, D, E, G].

, , [A, B, C, D, E, F], [A, B, C, D, E, G], .

, CoreData , , . .

, , . , 20 , 1 , 20 , , .

.

+1

Source: https://habr.com/ru/post/1774593/


All Articles