Sbh*_*klr 6 core-data objective-c ios restkit
自从将核心数据逻辑迁移到RKManagedObjectStore以来,我遇到了严重的问题.我在视图控制器的主线程中设置了一个NSFetchedResultsController,其上下文设置为[NSManagedObject managedObjectContext]:
assert([NSThread isMainThread]);
NSManagedObjectContext* context = [NSManagedObject managedObjectContext];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:[Item fetchRequest] managedObjectContext:context sectionNameKeyPath:nil cacheName:@"Master"];
Run Code Online (Sandbox Code Playgroud)
我在上下文中插入对象,如下所示:
Item* item = [Item object];
item.name = @"Foo";
[[RKObjectManager sharedManager].objectStore save];
Run Code Online (Sandbox Code Playgroud)
但是获取的结果控制器不会收到有关更改的通知.因此我手动注册了一个通知:
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
NSLog(@"Context changed");
[self.fetchedResultsController performFetch:nil];
[self.tableView reloadData];
}];
Run Code Online (Sandbox Code Playgroud)
我认为这应该是不必要的,因为RKManagedObjectStore会在不同的上下文中合并更改.第二,删除我试过的Item对象
[item deleteEntity];
Run Code Online (Sandbox Code Playgroud)
这产生了一个错误,表示无法在另一个上下文中删除该对象.这显然是正确的,但是为什么上下文不是主线程的相同实例?在删除en实体之前,我也在视图控制器内调用以下内容:
assert([NSThread isMainThread]);
NSManagedObjectContext* sameContext1 = [NSManagedObject managedObjectContext];
NSManagedObjectContext* sameContext2 = self.fetchedResultsController.managedObjectContext;
assert(sameContext1 == sameContext2); //FAILS
Run Code Online (Sandbox Code Playgroud)
查看使用[NSManagedObject managedObjectContext]时调用的RKManagedObjectStore的managedObjectContext getter实现,应返回每个线程的相同实例:
-(NSManagedObjectContext*)managedObjectContext {
NSMutableDictionary* threadDictionary = [[NSThread currentThread] threadDictionary];
NSManagedObjectContext* backgroundThreadContext = [threadDictionary objectForKey:RKManagedObjectStoreThreadDictionaryContextKey];
...
}
Run Code Online (Sandbox Code Playgroud)
经过数小时的调试后,我终于找到了那个讨厌的bug.问题是RKObjectManager持有一个参考RKManagedObjectStore.但不知何故,当使用ARC时,引用不会保留在[RKObjectManager sharedManager]实例中并且正在被释放.这会导致刷新线程本地缓存.因此,托管对象上下文合并不起作用,因为在每次访问时都会创建新的托管上下文.修复很容易.只需RKManagedObjectStore在您的App Delegate中保留一个强有力的参考,您就完成了.
| 归档时间: |
|
| 查看次数: |
4387 次 |
| 最近记录: |