我尝试使用Restkit和RKPaginator加载api的所有页面(在加载第一页之前我不知道页数)。
10次尝试中有1次,我收到以下错误
'NSInternalInconsistencyException',原因:'当一个人正在进行加载时无法执行加载。'
当此问题没有出现时,该功能正在按预期工作
我使用以下代码:
- (void)loadAllPagesForEntity:(NSString*)entityName
success:(void (^)(RKPaginator *paginator, NSArray *objects, NSUInteger page))success
{
URObjectManager *objectManager = [URObjectManager sharedManager];
NSString *requestString = [NSString stringWithFormat:@"%@?page=:currentPage&size=:perPage",entityName];
RKPaginator* myPaginator = (RKPaginator*)[objectManager paginatorWithPathPattern:requestString];
myPaginator.perPage = 50; // this will request /posts?page=N&per_page=20
[myPaginator setCompletionBlockWithSuccess:^(RKPaginator *paginator, NSArray *objects, NSUInteger page)
{
if ([paginator hasNextPage]) { [paginator loadNextPage]; }
else if (success) { success(paginator, objects, page); }
}
failure:^(RKPaginator *paginator, NSError *error)
{
NSLog(@"Failure: %@", error);
}];
[myPaginator loadPage:0];
}
此代码在更多实体上调用:
[self loadAllPagesForEntity:@"entity1" success:nil];
[self loadAllPagesForEntity:@"entity2" success:nil];
...
[self loadAllPagesForEntity:@"entity n" success:nil];
我的程序崩溃并被RKPaginator.m中的以下断言之一阻止: l.158
NSAssert(self.isLoaded, @"Cannot determine hasNextPage: paginator is not loaded.");
或
l.177
NSAssert(! self.objectRequestOperation, @"Cannot perform a load while one is already in progress.");
在成功块中测试hasNextPage或执行loadNextPage是不正确的? 这样做的正确方法是什么?
我尝试过没有成功使用:
[paginator performSelector:@selector(loadNextPage) onThread:[NSThread currentThread] withObject:nil waitUntilDone:NO];
在延迟纠正问题后执行选择器但不是可接受的解决方案。
答案 0 :(得分:0)
似乎是RKPaginator.m中的一个错误(Restkit 0.23)。我会在找到时间后立即在github上填写请求。
似乎成功回调和请求操作的完成不是在同一个线程中完成的。
因此,当调用成功时,并不总是设置isLoaded。
我将代码更改为在执行成功回调之前始终调用操作结束。 它为我做了诀窍。
评论l.198
// Add KVO to ensure notification of loaded state prior to execution of completion block
//[self.objectRequestOperation addObserver:self forKeyPath:@"isFinished" options:0 context:nil];
L.221
[self.objectRequestOperation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self operationFinished];
if (self.successBlock) {
self.successBlock(self, [mappingResult array], self.currentPage);
}
}
添加功能
-(void)operationFinished
{
RKObjectRequestOperation*oro = self.objectRequestOperation;
self.objectRequestOperation = nil;
self.loaded = (oro.mappingResult != nil);
self.mappingResult = oro.mappingResult;
self.error = oro.error;
}
答案 1 :(得分:0)
我在RestKit github页面上发布了测试解决方案。 我希望它很快会合并,但是如果你需要它,现在可以随意使用我的叉子。
https://github.com/RestKit/RestKit/pull/2156
:)