UITableView reloadData占用了太多时间

时间:2012-03-17 19:05:04

标签: ios uitableview sdk reloaddata tbxml

我正在使用TBXML + HTTP从网站获取XML数据。我想要做的是用处理过的数据填充UITableView。 我已经创建了一个包含所有条目的NSMutableArray,并且就此而言,一切正常。 问题是,在成功从服务器获取数据并将其存储在数组中之后,我尝试使用reloadData更新表以显示数据。

用20行填充表大约需要5秒钟。奇怪的是,提取发生得非常快,因此数据可以立即获得。我不明白花了这么长时间。以下是日志中的一些信息:

2012-03-17 18:46:01.045 MakeMyApp[4571:207] numberOfSectionsInTableView: 1
2012-03-17 18:46:01.047 MakeMyApp[4571:207] numberOfRowsInSection: 0
2012-03-17 18:46:01.244 MakeMyApp[4571:1f03] numberOfSectionsInTableView: 1
2012-03-17 18:46:01.245 MakeMyApp[4571:1f03] numberOfRowsInSection: 20
2012-03-17 18:46:01.245 MakeMyApp[4571:1f03] Ok, I'm done. 20 objects in the array.
2012-03-17 18:46:01.246 MakeMyApp[4571:1f03] Finished XML processing.
2012-03-17 18:46:06.197 MakeMyApp[4571:1f03] cellForRowAtIndexPath:

正如您所看到的,它会激发对numberOfSectionsInTableView: / numberOfRowsInSection:两次:第一个是视图加载时,第二个是我执行时[self.tableView reloadData];

您可以看到,在不到一秒的时间内,数组将填充20个对象,并完成处理XML的所有工作。 cellForRowAtIndexPath:如何在5秒后解雇?

以下是可能有助于发现问题的代码的一些部分:

- (void)createRequestFromXMLElement:(TBXMLElement *)element {
    // Let's extract all the information of the request
    int requestId = [[TBXML valueOfAttributeNamed:@"i" forElement:element] intValue];

    TBXMLElement *descriptionElement = [TBXML childElementNamed:@"d" parentElement:element];
    NSString *description = [TBXML textForElement:descriptionElement];

    TBXMLElement *statusElement = [TBXML childElementNamed:@"s" parentElement:element];
    int status = [[TBXML textForElement:statusElement] intValue];

    TBXMLElement *votesCountElement = [TBXML childElementNamed:@"v" parentElement:element];
    int votesCount = [[TBXML textForElement:votesCountElement] intValue];    

    // Creating the Request custom object
    Request *request = [[Request alloc] init];

    request.requestId = requestId;
    request.description = description;
    request.status = status;
    request.votes_count = votesCount;

    [requestsArray addObject:request];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    appListCell *cell = (appListCell *)[tableView dequeueReusableCellWithIdentifier:@"appListCell"];

    Request *request = [requestsArray objectAtIndex:indexPath.row];

    cell.appIdLabel.text = [NSString stringWithFormat:@"#%d", request.requestId];
    cell.appTextLabel.text = request.description;
    cell.appVotesLabel.text = [NSString stringWithFormat:@"%d votes", request.votes_count];

    return cell;
}

非常感谢!

编辑:

- (void)traverseXMLAppRequests:(TBXMLElement *)element {
    int requestCount = 0;
    TBXMLElement *requestElement = element->firstChild;

    // Do we have elements inside <re>?
    if ((requestElement = (element->firstChild))) {
        while (requestElement) {
            [self createRequestFromXMLElement:requestElement];

            requestCount++;

            requestElement = [TBXML nextSiblingNamed:@"r" searchFromElement:requestElement];
        }
    }

    [self.tableView reloadData];   

    NSLog(@"Ok, I'm done. %d objects in the array.", [requestsArray count]);

}

编辑2:我尝试只获取1行而不是20行的信息,延迟完全相同。

3 个答案:

答案 0 :(得分:16)

我知道这是一个真的旧问题,但我只是遇到了完全相同的问题,并认为我可能知道原因。可能会帮助那些偶然发现同样问题的人...

我怀疑你的reloadData调用是在后台线程上发生的,而不是主线程。你所描述的是这个的确切影响 - 代码运行但更新用户界面有很长的延迟(5-10秒)。

尝试将reloadData调用更改为:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.tableView reloadData];
});

答案 1 :(得分:8)

您正在reloadData

以外的主题上调用mainThread

请务必在主线程上重新加载tableView的数据,如下所示:

<强> OBJ-C:

[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

Swift 3:

DispatchQueue.main.async {
   self.tableView.reloadData()
}

答案 2 :(得分:0)

在哪里:

- (void)createRequestFromXMLElement:(TBXMLElement *)element

被叫?听起来你可能会发出20个Web请求来获取该文件内容。这肯定会让事情变得缓慢(而不是做一个请求来获取整个XML文件并在本地解析)。

您可以发布整个VC代码吗?