UITableView - 背景中的AFNetworking操作冻结滚动

时间:2013-09-23 14:40:28

标签: ios objective-c uitableview asynchronous afnetworking

我有一个带UITableViewController的示例应用程序。

在facebook新闻源中,应用程序应该首次下载X新闻,然后在用户滚动时逐步获取新闻。

这是我的实施:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

if (indexPath.row == self.newsList.count-PADDLE_BEFORE_FETCHING && !cantFetchMore)
    if (!fetching){
        fetching = YES;

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
            [self fetchNews];
        });


    }

}

(我们的想法是在我们到达N-PADDLE_BEFORE_FETCHING单元时开始获取更多新闻,只有当我们仍然可以获取一些 - 见下文 - 并且如果仍然没有正在运行获取)

然后执行fetchNews:

-(void)fetchNews{


    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSString *url = [NSString stringWithFormat:@"%@%@%@%@%d%@",HOSTNAME,GET_NEWS,[defaults objectForKey:@"oAuthToken"],@"&limit=",FETCH_SIZE_NEWS,[NSString stringWithFormat:@"&offset=%d",self.newsList.count]];

    NSURLRequest *request =[[NSURLRequest alloc] initWithURL:[NSURL URLWithString:url]];


    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

        #if DEVELOPMENT_MODE
                NSLog(@"News : %@",JSON);
                NSLog(@"Response : %@\n Request : %@",response,request);
        #endif

        //NSLog(@"Number of news fetched : %d",((NSArray*)JSON[@"data"]).count);

        for (NSDictionary *d in JSON[@"data"]){
            News *new = [[News alloc] initWithDictionary:d];
            [self.newsList addObject:new];
            new = nil;
        }


        if ((((NSArray*)JSON[@"data"]).count)%FETCH_SIZE_NEWS !=0) cantFetchMore = YES;
        //NSLog(@"%d cantFetch",cantFetchMore);

        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

        [self.tableView reloadData];

        fetching = NO;

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"Request error : %@ %@ %@",request,error, JSON);
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        fetching = NO;

    }];


    [operation start];

}

这将从服务器获取FETCH_SIZE_NEWS附加消息,该消息从goodList(当前大小的newsList数组)开始。 此外,如果获取的新闻%FETCH_SIZE_NEWS的计数与0不同,则意味着我们无法获取其他新闻(这将阻止在滚动UITableView时调用Web服务)。

我的问题是,当完成提取时(当我看到活动轮在状态栏中运行时),它会阻止GUI,我无法继续从n-PADDLE_BEFORE_FETCHING单元格向下滚动到n个单元格,或者甚至向上滚动到之前加载的单元格。

我真的不明白为什么AFNetworking应该以异步方式运行。

有什么想法吗?

谢谢,

2 个答案:

答案 0 :(得分:1)

完成块中的for循环正在主线程上运行,可能导致减速。尝试将该代码发送到另一个线程/队列。

答案 1 :(得分:0)

如上所述,购买Guy Kogus,AFNetworking操作完整区块内的处理是在滚动时在主线程上添加一些冰箱。

刚刚添加

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{//processing block}

在完整的块(特别是foreach循环)中,这要好得多。

由于