关于核心数据和关系的并发性

时间:2011-11-25 09:55:42

标签: core-data concurrency

我想在辅助线程上插入数据,然后跟踪主线程中的更改。

我有两个实体,它们被设置为Inverse。

@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

如果我没有在fetchedResultsController中获取Entity2但是实体1,我的应用程序运行正常。但我想获取entity2,然后使用entity2.entity1.data访问entity1.who可以帮助我。

1 个答案:

答案 0 :(得分:1)

我发现了我的错误,我在fetchrequest中使用了这种关系作为排序描述符。

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

如果我使用其他属性作为sortdescriptor,应用程序就可以了。