为什么在滚动表格时获取数据会变慢?

时间:2012-11-04 05:09:42

标签: iphone ios afnetworking

下面的代码几乎与我在ASI中使用的代码相同,但现在我正在使用AFNetworking。我的猜测是它很慢,因为它在主线程上运行成功块。我试图将successCallbackQueue设置为一个新队列,但它似乎没有工作。它只是非常慢,并没有有效地做到这一点。如何加快速度或确保它在后台线程中运行?

#define kPerPage 10

- (void) pullData {
    NSURL *url = [API homeRecentUrlWithPage:self.currentRecentPage limit:kPerPage];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    dispatch_queue_t requestQueue = dispatch_queue_create("requestQueue", NULL);
    AFJSONRequestOperation *operation;
    operation.successCallbackQueue = requestQueue;
    operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        NSArray* modelArray = [JSON objectForKey:@"models"];

        for (int i = 0; i < [modelArray count]; i++)
        {
            Model *b = [Model alloc];
            b = [b initWithDict:[Model objectAtIndex:i]];
            [self.otherArray addObject:b];
        }
        [_modelTable reloadData];

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"%@", [error userInfo]);
    }];
    [operation start];
}


- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString* identifier = @"ModelTableCell";
    cell = (ModelTableCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell == nil) {
        cell = [[ModelTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
        cell.selectionStyle = UITableViewCellAccessoryNone;
    }
    if([indexPath row] == (self.currentRecentPage-1) * kPerPage + 5) {
        NSLog(@"%d aaa", self.currentRecentPage);

        self.currentRecentPage++;
        [self pullData];
    }


    Model *b = [self.models objectAtIndex:[indexPath row]];
    [cell populateWithModel:b];
    return cell;
}

1 个答案:

答案 0 :(得分:1)

我认为您没有正确设置回调队列

您将回调队列分配给某个操作,但随后您创建了一个覆盖它的操作。

// You create the queue
dispatch_queue_t requestQueue = dispatch_queue_create("requestQueue", NULL);

// You declare an operation, but you don't create it.
AFJSONRequestOperation *operation;

// You assign the requestQueue to this uninitialised operation
operation.successCallbackQueue = requestQueue;

// You create the operation here, and it overwrites the requestQueue you have set
operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

您应该在创建操作后设置successCallbackQueue

编辑添加更多

我的阅读更多。使用GCD和Mountain Lion或iOS6应用程序,如果使用ARC,它将负责队列的内存管理。所以当你在一个方法中声明一个队列,并将它分配给一个只分配值的属性时(因为在AFNetworking中声明了successCallbackQueue属性),那么队列就会被释放,并且操作不会保留它,所以它是留下一个NULL队列,你得到了错误的访问权。

所以,解决这个问题的方法是在你的控制器中安装一个iVar来保持对队列的强引用,这样即使操作没有保留队列,你的控制器也会这样,所以它不会被清除来自你。