о параллелизме с основными данными и отношениями - PullRequest
3 голосов
/ 25 ноября 2011

Я хочу вставить данные во вторичный поток, а затем отслеживать изменения в основном потоке.

У меня есть две сущности, и они были установлены в обратном порядке.

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

Я регистрирую уведомление о сохранении контекста в основном потоке.

 //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];

 }

выборка из coredata, она будет выполняться в основном потоке

-(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!");

  }

это запуск приложения.

   -(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];  
   });
    }

при сборке я получил ошибку

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

и ошибка возникает в NSFetchedResultsController обрабатывать контекстное уведомление, это стек вызовов:

__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

Если я не получаю Entity2, а Entity1 в fetchedResultsController, мое приложение запускается нормально. Но я хочу получить entity2, а затем использовать entity2.entity1.data для доступа к entity1.who, которые могут мне помочь.

1 Ответ

1 голос
/ 28 ноября 2011

Я нашел свою ошибку, я использовал отношение как дескриптор сортировки в fetchrequest.

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

если я использую другой атрибут для сортировки дескриптора, приложение будет в порядке.

...