自从将核心数据逻辑迁移到RKManagedObjectStore以来,我遇到了严重的问题。我在 View Controller 的主线程中设置了一个上下文设置为[NSManagedObjectmanagedObjectContext]的NSFetchedResultsController:
assert([NSThread isMainThread]);
NSManagedObjectContext* context = [NSManagedObject managedObjectContext];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:[Item fetchRequest] managedObjectContext:context sectionNameKeyPath:nil cacheName:@"Master"];
我在这样的上下文中插入对象:
Item* item = [Item object];
item.name = @"Foo";
[[RKObjectManager sharedManager].objectStore save];
但是获取的结果 Controller 不会收到有关更改的通知。因此,我手动注册了一个通知:
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
NSLog(@"Context changed");
[self.fetchedResultsController performFetch:nil];
[self.tableView reloadData];
}];
我认为这实际上没有必要,因为RKManagedObjectStore合并了不同上下文中的更改。第二,删除我尝试过的Item对象
[item deleteEntity];
这产生了一个错误,指出无法在另一个上下文中删除该对象。显然,这是正确的,但是为什么,上下文是否与主线程的实例不同?在删除en实体之前,我也在 View Controller 内调用以下命令:
assert([NSThread isMainThread]);
NSManagedObjectContext* sameContext1 = [NSManagedObject managedObjectContext];
NSManagedObjectContext* sameContext2 = self.fetchedResultsController.managedObjectContext;
assert(sameContext1 == sameContext2); //FAILS
查看RKManagedObjectStore的managedObjectContext getter实现,该实现在使用[NSManagedObjectmanagedObjectContext]时被调用,每个线程应返回相同的实例:
-(NSManagedObjectContext*)managedObjectContext {
NSMutableDictionary* threadDictionary = [[NSThread currentThread] threadDictionary];
NSManagedObjectContext* backgroundThreadContext = [threadDictionary objectForKey:RKManagedObjectStoreThreadDictionaryContextKey];
...
}
最佳答案
经过数小时的调试,我终于找到了那个令人讨厌的错误。问题在于RKObjectManager
拥有对RKManagedObjectStore
的引用。但是以某种方式使用ARC时,该引用不会保留在[RKObjectManager sharedManager]
实例中,而是会被释放。这将导致线程本地缓存的刷新。因此,托管对象上下文合并无法正常工作,因为在每次访问时都会创建一个新的托管上下文。修复很容易。只要在您的App Delegate中牢牢引用RKManagedObjectStore
,就可以完成。
关于objective-c - Restkit [NSManagedObjectmanagedObjectContext]返回不同的实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8941412/