调用reloadData后出现UITableView性能问题

时间:2013-11-12 21:31:39

标签: ios objective-c performance uitableview

我是一名Android开发人员,致力于我的第一个iOS项目。我有一个显示近37,500行的UITableView。杂货店中每件商品一行。该列表有3列,一列包含项目名称,另外两列包含其他重要数据。这些列是可排序的,为了处理排序,我根据需要对数据数组进行排序,并在对数组进行排序后调用[tableView reloadData]。这样可以正常工作,除非在重新加载主线程锁定工作的数据后至少有几秒钟的延迟。我对列出性能并不陌生,因为我必须在Android中多次制作流畅的列表。所以我可以告诉我,实际上并没有做太多事情。我唯一能想到的就是我的数组中的大量项目。以下是相关代码:

以下是我重写的表格方法:

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     return [self.data count];
 }

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"CustomCell";
ReplenishListCell *cell = [self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

if (cell == nil) {
    cell = [[ReplenishListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}

NSMutableDictionary *dictData = [self.data objectAtIndex:indexPath.row];

cell.nameLabel.text = dictData[@"item-description"];
cell.firstLicationColumnLabel.text = dictData[@"store-count"];
cell.secondLicationColumnLabel.text = dictData[@"other-count"];

return cell;
}

-(void)tableView:(UITableView *)replenishTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self showActivityIndicator];

ReplenishListCell *cell = (ReplenishListCell*) [replenishTableView cellForRowAtIndexPath:indexPath];
NSString *nameClicked = cell.nameLabel.text;

[database getItemByName:nameClicked :self];
}

以下是我用来对数组进行排序的方法:

-(void) sortArray:(NSString *) dictionaryKey {
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:dictionaryKey ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
NSArray *sortedArray = [data sortedArrayUsingDescriptors:sortDescriptors];

[data removeAllObjects];
[data addObjectsFromArray:sortedArray];

[self.tableView reloadData];
}

在致电[self.tableView reloadData]之前,我没有遇到任何性能问题。所以我想知道是否有一些我遗漏的东西,或者是否有更好的方法可以重新加载reloadData以外的数据?任何帮助将不胜感激。我现在花了几个小时调试和谷歌搜索,我还没有提出解决方案。

3 个答案:

答案 0 :(得分:1)

UI悬挂的一个可能原因是您正在删除并添加两个阵列之间的所有37.5k对象。

尝试更改此内容:

[data removeAllObjects];  
[data addObjectsFromArray:sortedArray];

到此:

data = sortedArray;

答案 1 :(得分:1)

对于大型操作,您应该使用后台队列,而不是在主队列上执行该操作并阻止UI。在后台操作可以​​获得数据后,您可以在主队列上调用reloadData:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
            [self sortArray:<# your key #>];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });
});

同样考虑使用保罗的建议,如前面的答案。

答案 2 :(得分:1)

您的代码看起来不错。就像@paulrehkugler在他的回答中所说的那样,你只需要对数组进行排序data = sortedArray

根据您拥有的数据量,请考虑在后台线程中预先排序您的数据。根据我的计算,如果你保留3个不同排序顺序的数组,那么37,500个对象需要150K的内存。因此,当用户选择按特定列排序时,您已经对数据进行了排序,并且您只需交换用作数据源的数组。对于用户来说,那么分类几乎是瞬间出现的。