Master data and multithreading

I read Marcus Zarra’s chapter on multithreading in my book Basic Data and looked rather closely at its sample code. But his code and others that I found elsewhere seem to be concentrated in background processes that shouldn't know about each other. These examples are good for importing a tree structure, but they do not affect the import of a more general (complex) structure, such as a directed acyclic graph.

In my case, I am trying to analyze the hierarchy of C ++ classes and would like to use as many NSOperations as possible. I would like to create an instance of NSManagedObject for each class I encounter, and I would like to combine different NSManagedObjectContexts every time it is saved.

Aside: I can get everything to work with one NSOperation, which iterates through the files and parses them one at a time. This implementation uses the -mergeChanges method: an approach that calls -mergeChangesFromContextDidSaveNotification: on the main thread, MOC works well.

But ideally, I would have one NSOperation, iterate over the source files and run NSOperations to parse each file. I tried several approaches - but it seems that not everything is correct. Most promising was that every NSOperation observe NSManagedObjectContextDidSaveNotification. With -mergeChanges: looks like this:

- (void) mergeChanges:(NSNotification *)notification
 {
 // If locally originated, then trigger main thread to merge.
 if ([notification object] == [self managedObjectContext])
  {
  AppDelegate *appDelegate = (AppDelegate*)[[NSApplication sharedApplication] delegate];
  NSManagedObjectContext *mainContext = [appDelegate managedObjectContext];

  // Merge changes into the main context on the main thread
  [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
         withObject:notification
         waitUntilDone:YES];
  return;
  }
   // If not locally originated, then flag need to merge with in this NSOperation thread.  
 [self setNeedsToMerge:YES];
 [self setMergeNotification:notification];
 }

, NSOperation main() ivar 'needsToMerge' . , -mergeChangesFromContextDidSaveNotification: MOC NSNotifications. requireToMerge reset. , , -mergeChangesFromContextDidSaveNotification: MOC.

, , :

: - objc .

NSPeristentStoreCoordinator - , NSManagedObjectContext -save: -save: -mergeChangesFromContextDidSaveNotification: , PSC.

, .

+5
2

, , :

NSOperation, :

NSMutableArray * changeNotifications;
NSLock  * changeNotificationsLock;
NSManagedObjectContext  * localManagedObjectContext;

NSOperation :

[self.changeNotificationsLock lock];
for(NSNotification * change in self.changeNotifications){
    [self.localManagedObjectContext mergeChangesFromContextDidSaveNotification:change];
}
if([self.changeNotifications count] >0){
    [self.changeNotifications removeAllObjects];
}
[self.changeNotificationsLock unlock];

NSError *error = nil;   
[self.localManagedObjectContext save:&error]

, , NSMutableArray , changeNotifications. changeNotifications - , , .

, , , NSOperation, . , , NSOperation, self.changeNotifications

- (void) mergeChanges:(NSNotification *)notification
 {
 // If not locally originated, then add notification into change notification array
 // this notification will be treated by the NSOperation thread when needed.
 if ([notification object] != self.localManagedObjectContext)
  {
     [self.changeNotificationsLock lock];
     [self.changeNotifications addObject:notification];
     [self.changeNotificationsLock unlock];
  }

 //Here you may want to trigger the main thread to update the main context     

}

, ! 100%, , . , NSManagedObject . , , .

+2

:

- (void)mergeChanges:(NSNotification *)notification;
{
//AppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
NSManagedObjectContext *mainContext = [appDelegate managedObjectContext];

// Merge changes into the main context on the main thread
[mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) 
                              withObject:notification
                           waitUntilDone:YES];  
}

-(void) main {
// Register context with the notification center
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
[nc addObserver:self
       selector:@selector(mergeChanges:) 
           name:NSManagedObjectContextDidSaveNotification
         object:managedObjectContext];

, managedObjectContext :

managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:[appDelegate persistentStoreCoordinator]];
[managedObjectContext setUndoManager:nil];

, - , moc. , , moc , - .

0

All Articles