user797876
user797876

Reputation: 93

about concurrency with core data and relationship

i want to insert data on secondary thread and then track changes in main thread.

I have two Entitys,and they was set Inverse.

@interface Entity1 :  NSManagedObject 
    @property (nonatomic, retain) NSString * data;
    @property (nonatomic, retain) Entity2 * entity2;
@end
@interface Entity2 :  NSManagedObject  
    @property (nonatomic, retain) Entity1 * entity1;
@end

I register context save notificaton in main thread.

 //this managedObjectContext run in main thread
 -(NSManagedObjectContext *)managedObjectContext_mainThread {
      ......
      [[NSNotificationCenter defaultCenter] 
                                 addObserver:self
                            selector:@selector(contextDidSave:)
                                name:NSManagedObjectContextDidSaveNotification                                 
                              object:nil];      

         return managedObjectContext_mainThread ;
 }

 //pass notification
 - (void)contextDidSave:(NSNotification *)notification
 {
 ...... 
    [managedObjectContext_mainThread  
               mergeChangesFromContextDidSaveNotification:notification];

 }

fetch from coredata,it will run in main thread

-(NSFetchedResultsController *)fetchedResultsController
 {
   if (fetchedResultsController == nil) {
     NSManagedObjectContext *moc = [self managedObjectContext_mainThread];
     NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity2"         
                                                      inManagedObjectContext:moc];
     NSSortDescriptor *sd = [[NSSortDescriptor alloc] initWithKey:@"entity1" 
                                                               ascending:YES];
     .....

    }

   return fetchedResultsController; 
  }

  //NSFetchedResultsControllerDelegate, in this functions updata my UI
  -(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
  {
 NSLog(@"controllerDidChangeContent start!");

  }

this is the app start.

   -(void)loadView {

    myQueue = dispatch_queue_create("myQueue", NULL);

    // this context is managedObjectContext_mainThread and run in main thread
    NSArray *results = [self fetchedResultsController];

    //insert Data oparation  in managedObjectContext_otherThread and myQueueu
    dispatch_async(myQueue, ^{
        ......      
    Entity1 *entity1 = 
                     [NSEntityDescription insertNewObjectForEntityForName:@"Entity1" 
                            inManagedObjectContext:managedObjectContext_otherThread];
    Entity2 *entity2 = 
                    [NSEntityDescription 
                     insertNewObjectForEntityForName:@"Entity2"  
                              inManagedObjectContext:managedObjectContext_otherThread];
    entity1.data = @"myData";
    entity1.entity2 = entity2;
       [[self managedObjectContext_otherThread] save:nil];  
   });
    }

when i build i got an error

-[Entity1 compare:]: unrecognized selector sent to instance 0x4d3ec90

and the error occur in NSFetchedResultsController handle context notification,this is the call stack:

__exceptionPreprocess + 185
objc_exception_throw + 47
-[NSObject(NSObject) doesNotRecognizeSelector:] + 187
___forwarding___ + 966
CF_forwarding_prep_0 + 50
_NSCompareObject + 76
+[NSFetchedResultsController(PrivateMethods)  
  _insertIndexForObject:inArray:lowIdx:highIdx:sortDescriptors:] + 286
-[NSFetchedResultsController(PrivateMethods) _postprocessInsertedObjects:] + 402
-[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] + 1804

if i don't fetch the Entity2 but Entity1 in fetchedResultsController,my app run ok.but I want to fetch entity2,and then use entity2.entity1.data to access entity1.who can help me.

Upvotes: 3

Views: 317

Answers (1)

user797876
user797876

Reputation: 93

I have found my mistake, I used the relationship to be sort descriptor in fetchrequest.

 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity2"         
                                                  inManagedObjectContext:moc];
 NSSortDescriptor *sd = [[NSSortDescriptor alloc] initWithKey:@"entity1" 
                                                           ascending:YES];

if I use other attribute to be sortdescriptor, the app will be OK.

Upvotes: 1

Related Questions