2014-03-13 24 views
2

我尝试使用Restkit和RKPaginator加载api的所有页面(我不知道加载第一页之前的页面数量)。在成功块中加载下一页时出现RKPaginator错误

1出10次尝试,我得到以下错误

“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

有多少,这些都是你在同一时间运行?你有没有对操作队列做任何事情? iOS版? OSX? – Wain

+0

我下载了20个关于ios7/ipad的约10个实体。我不使用操作队列(但Restkit使用它在地下不是吗?)。我也尝试使用getPageAtPath和page作为参数来初始化循环内的20个页面的下载,并且不会遇到任何问题(除了页面的数量是固定的)。 – nonobzh

+0

如果请求成功完成,那么您应该能够启动下一页。我会打开跟踪日志。记录服务器响应。并改变'[objectManager.operationQueue setMaxConcurrentOperationCount:5];' – Wain

回答

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; 
}