Reputation: 93
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
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