Restkit [NSManagedObject managedObjectContext] returns different instances

I'm having serious problems since I migrated my main data logic to RKManagedObjectStore. I configure NSFetchedResultsController with the context set to [NSManagedObject managedObjectContext] in the main thread in the view controller:

assert([NSThread isMainThread]); NSManagedObjectContext* context = [NSManagedObject managedObjectContext]; NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:[Item fetchRequest] managedObjectContext:context sectionNameKeyPath:nil cacheName:@"Master"]; 

I insert objects in context as follows:

 Item* item = [Item object]; item.name = @"Foo"; [[RKObjectManager sharedManager].objectStore save]; 

But the recipient of the results does not receive notification of changes. Thus, I registered the notification manually:

 [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification object:nil queue:nil usingBlock:^(NSNotification *note) { NSLog(@"Context changed"); [self.fetchedResultsController performFetch:nil]; [self.tableView reloadData]; }]; 

This is really not necessary. I think since RKManagedObjectStore combines changes in different contexts. Secondly, to delete the Item object, I tried

 [item deleteEntity]; 

An error has occurred indicating that the object cannot be deleted in another context. This is obviously true, but WHY the hell is the context is not the same instance for the main thread? I call the following inside the view controller before deleting the en entity:

 assert([NSThread isMainThread]); NSManagedObjectContext* sameContext1 = [NSManagedObject managedObjectContext]; NSManagedObjectContext* sameContext2 = self.fetchedResultsController.managedObjectContext; assert(sameContext1 == sameContext2); //FAILS 

Looking at the RKManagedObjectStore managedObjectContext implementation that is called when using [NSManagedObject managedObjectContext], the same instance for the stream should be returned:

 -(NSManagedObjectContext*)managedObjectContext { NSMutableDictionary* threadDictionary = [[NSThread currentThread] threadDictionary]; NSManagedObjectContext* backgroundThreadContext = [threadDictionary objectForKey:RKManagedObjectStoreThreadDictionaryContextKey]; ... } 
+6
source share
1 answer

I finally discovered this nasty bug after hours of debugging. The problem is that RKObjectManager contains a link to RKManagedObjectStore . But for some reason, when using ARC, this link is not stored in the [RKObjectManager sharedManager] and is freed. This causes the local thread cache to be flushed. Therefore, merging managed objects does not work, because each access creates a new managed context. Easy to fix. Just keep a strong link to RKManagedObjectStore in your application deletion, and you're done.

+9
source

Source: https://habr.com/ru/post/906474/


All Articles