コアデータおよび関係との並行性について

セカンダリスレッドにデータを挿入し、メインスレッドの変更を追跡したい。

私は2つのエンティティを持っており、それらは逆に設定されています。

@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をフェッチしないでfetchedResultsControllerのEntity1を実行した場合、私のアプリケーションはok.butを実行します。私はentity2をフェッチし、次にentity2.whiteにアクセスするためにentity2.whiteを使用します。

3

1 答え

私は自分の間違いを見つけました、私はfetchrequestで並べ替え記述子にするために関係を使用しました。

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

私がsortdescriptorに他の属性を使用する場合、アプリはOKになります。

1
追加された