Ios RESTKit0.2加载两个具有相同实体和不同谓词的不同表时遇到问题
以下是我尝试做的简化版本: 我有一个应用程序,它使用UITabBarController作为根控制器。 在两个选项卡中,我有一个包含自定义UITableViewController的UINavigationController 其中一个表视图用于显示“特色”项目,另一个用于显示“用户”项目 第一个的API端点是:/API/items/featured 另一个端点是:/api/items/user 我在AppDelegate中设置所有内容的整个过程。m:Ios RESTKit0.2加载两个具有相同实体和不同谓词的不同表时遇到问题,ios,restkit,restkit-0.20,Ios,Restkit,Restkit 0.20,以下是我尝试做的简化版本: 我有一个应用程序,它使用UITabBarController作为根控制器。 在两个选项卡中,我有一个包含自定义UITableViewController的UINavigationController 其中一个表视图用于显示“特色”项目,另一个用于显示“用户”项目 第一个的API端点是:/API/items/featured 另一个端点是:/api/items/user 我在AppDelegate中设置所有内容的整个过程。m: // Configure the obje
// Configure the object manager
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:API_SERVER]];
objectManager.managedObjectStore = managedObjectStore;
[RKObjectManager setSharedManager:objectManager];
RKEntityMapping *entityMapping = [RKEntityMapping mappingForEntityForName:@"Item" inManagedObjectStore:managedObjectStore];
[entityMapping addAttributeMappingsFromDictionary:@{
@"id": @"itemID",
@"type": @"type",
@"created_at": @"created_at":
@"field1": @"field1"}];
// User Descriptor
RKResponseDescriptor *userDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping pathPattern:@"/api/items/user" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:userDescriptor];
// Featured Listing Decriptor
RKResponseDescriptor *featuredDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping pathPattern:@"/api/items/featured" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor];
然后在tableview控件中,我有以下内容(在第二个tableview控制器中,用“用户”代替“特色”)
现在,对于第一个选项卡,这一切都可以正常工作(目前它返回8个项目,类型为'featured',显示在表中)
当我切换到第二个选项卡时,问题就出现了。它当前仅返回1个type='user'项,并在以下情况下崩溃:
CoreData:错误:严重的应用程序错误。在核心数据更改处理期间捕获异常。这通常是NSManagedObjectContextObjectsIDChangeNotification的观察者中的错误。*-[\uu NSArrayM objectAtIndex:]:索引3超出了带有userInfo(null)的空数组的界限
如果我省略了“用户”选项卡上的谓词,则“特色”选项卡工作正常,“用户”选项卡在其表中获取“特色”项,其中“用户”项位于顶部
由于两个tableview控件的代码完全相同,除了“用户”和“特色”之外,我不知道问题出在哪里。在创建和配置“获取结果”控制器时,不要使用缓存。目前,他们都在使用
@“Master”
缓存,这将导致他们尝试共享不合适的信息,因为获取请求不同。您是否在UITableViewController上实现了NSFetchedResultsControllerDelegate更改方法?在使用RestKit/RKGist作为模板时,我发现了一个类似的错误,在删除了这些更改方法并将控制器作为它们的代理删除后,这个错误消失了。这对我来说很有效,因为我不希望以这种方式收到有关更改的通知:我将fetchedResultsController的getter与结果的重新蚀刻分离开来,并在相应RKObjectRequestOperation的成功块中调用重新蚀刻。希望有帮助
编辑
在我的情况下,实际上我在一个UITableViewController中使用了两个NSFetchedResultsController:
在my.h界面中
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsOneController;
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsTwoController;
在.m实现中:
每一个都有一个各自的getter,用于调用雕刻出的重新蚀刻
- (NSFetchedResultsController *)fetchedResultsOneController
{
if (_fetchedResultsOneController != nil) {
return _fetchedResultsOneController;
}
[self refetchResultsOneController];
return _fetchedResultsOneController;
}
refetch仅包含构建fetch请求、实体描述、排序和fetch控制器的其余逻辑,如:
- (void) refetchResultsOneController
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = ...;
[fetchRequest setEntity:entity];
// set predicate for venue name
NSPredicate *predicate = [NSPredicate predicateWithFormat: ....];
[fetchRequest setPredicate:predicate];
[fetchRequest setFetchBatchSize:200];
NSSortDescriptor *distanceDescriptor = [[NSSortDescriptor alloc] initWithKey:...];
NSArray *sortDescriptors = @[distanceDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"SomeUniqueName"];
self.fetchedResultsOneController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsOneController performFetch:&error]) {
.. error handle...;
}
}
注:再蚀刻机是不同的;不同的实体和不同的NSPredicate,但ManagedObjectContext相同
在objectmanager操作的成功块中,调用refetch,对于resultsOne,它是一个简单的:
[objectManager getObjectsAtPath:[NSString stringWithFormat:@"...the path for results one...", venueId] parameters:queryParams
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self refetchResultsOneController];
[self.tableView reloadData];
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", [error localizedDescription]);
}];
这适用于我在一个UITableViewController中使用两个NSFetchResultsController。注意:我不允许用户操作编辑/删除fetchController中的对象(没有双向通信),但我只对读取那里的数据感兴趣,并且只有成功刷新远程服务器才能启动
希望这有帮助 我正面临着这个问题。你找到解决方案了吗?我的设置与darkrat相同,但我对两个视图控制器使用了不同的缓存名称,我仍然遇到这个问题。我已将缓存名称设置为零,但也没有任何帮助。您是如何实现FRC委托方法的?我只是有
-(void)controllerDidChangeContent:(NSFetchedResultsController*)控制器{[self.tableView reloadData];}
您介意发布一些代码吗?这真的很有帮助,谢谢你!如何刷新tableView?您是否使用类似于-(void)controllerDidChangeContent:(NSFetchedResultsController*)控制器{[self.tableView reloadData];}
?正确,但是我在objectmanager的成功块中调用它。很抱歉,这是之前的内容,我已经编辑了上面的内容。@sbonkosky这对你有用吗?我的项目被搁置了,我还没有空闲时间来验证这对我是否有效。如果它对您有效,那么我将继续并将此答案标记为正确。@darkrat我实际上以完全不同的方式进行了此操作,没有使用NSFetchedResultsController,因此我不确定此答案是否正确
[objectManager getObjectsAtPath:[NSString stringWithFormat:@"...the path for results one...", venueId] parameters:queryParams
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self refetchResultsOneController];
[self.tableView reloadData];
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", [error localizedDescription]);
}];