2013-04-06 81 views
0

我有一个自定义的UITableViewController类,在我的应用程序的几个ViewControllers之间共享。如何将getData与私有标志变量分开?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    ... 
    // Check if we are almost at the end of the scroll. If so, start fetching. 
    // Doing this here is better than overriding scrollViewDidEndDragging 
    if (indexPath.row >= [self.tableView numberOfRowsInSection:0] - 3) { 
     [self refill]; 
    } 

    return cell; 
} 

我愿做先发制人取的用户已经达到了页面底部之前。

但是,我注意到如果用户再次向上滚动然后再滚下来,我的VC会触发另一次抓取。

所以我想出了一个标志isFetching,它检查以防止重复读取。不幸的是,我正在运行异步代码,并且我需要一种方法在完成取回操作后重置此标志。

FeedVC:

- (void)refill { 
    if (self.continueFetching && !self.isFetching) { 
     NSLog(@"Fetching started"); 
     self.isFetching = true; 
     AFJSONRequestOperation *operation = [self.delegate refill:^{ 
      NSLog(@"Fetching completed"); 
      self.isFetching = false; 
     }]; 
     [self.pendingOperations addObject:operation]; 
    } 
} 

代表:

- (AFJSONRequestOperation *)refill:(void (^)(void))finishCallback { 
    return [[ItemStore sharedInstance] fetchItemsForFeed:^(int itemsFetched, int nextOffset, bool hasNextPage) { 
     finishCallback(); 
    } withFailureBlock:^{ 
     finishCallback(); 
    }]; 
} 

我觉得很痛苦围绕完成集团通过以翻转一个布尔值。有没有人有更好的建议?

+0

我想你应该尝试落实UITableView的滚动视图的委托方法的渐进式笔芯像scrollviewdragended。 – iphonic 2013-04-06 04:03:19

+0

这个逻辑可以设置在NSOperation的'completionBlock'上:'operation = [[ItemStore sharedInstance] fetchItemsForFeed:NULL withFailureBlock:NULL];''然后'[operation setCompletionBlock:yourBlock];' – 2013-04-06 04:55:08

+1

此外,您可以保留对获取操作的引用,并在完成块中将其取消。这样你可以通过粒度来取消操作,如果需要的话。 – 2013-04-06 04:57:15

回答

0

阐述:

typedef void(^block_t)(void); 
typedef void(^success_block_t)(int itemsFetched, int nextOffset, bool hasNextPage); 

FeedCV:

/****************************************************************************/ 
/*! 
@note assume the declarations: 
@property (nonatomic,strong) NSOperation* fetchOp; 
@property (nonatomic,strong) NSOperationQueue* operationQueue; 
*/ 
/****************************************************************************/ 
- (void) refill 
{ 
    if (self.fetchOp) { //fetch is in progress 
     return; 
    } 

    __block __weak id weakSelf = self; 
    block_t completionBlock = ^{ //this will happen on a BG thread 
     //Implement what ever logic seems to fit your FeedVC uppon completion 
     //This will be called on the operation thread, so don't update UI here 
     //Move to main thread UI updates 
     [weakSelf setFetchOp:nil]; 
    }; 

    self.fetchOp = [self.delegate refill:completionBlock]; 
//       successBlock:nil 
//        failBlock:nil]; 

    //If you can't change your delegate code then: 
    //self.fetchOp = [self.delegate refill:nil]; 
    //[self.fetchOp setCompletionBlock:completionBlock]; 

    [self.operationQueue addOperation:self.fetchOp]; 
} 
/****************************************************************************/ 

代表:

/****************************************************************************/ 
/*! 
@note If you can change this API add support for the blocks 
*/ 
/****************************************************************************/ 
- (AFJSONRequestOperation*) refill:(block_t)completionBlock 
//      successBlock:(success_block_t)success 
//       failBlock:(block_t)fail 
{ 
    AFJSONRequestOperation* op = [[ItemStore sharedInstance] fetchItemsForFeed:nil/*success*/ 
                   withFailureBlock:nil/*fail*/]; 
    [op setCompletionBlock:completionBlock]; 
    return op; 
} 
/****************************************************************************/ 
+0

等待这不会解决我的问题,因为self.fetchOp必须由其代表实施。我现在的问题是,我)我需要搭上fetchCompleted,ii)我不想将任何标志或变量暴露给我的代表 – disappearedng 2013-04-06 21:46:45