繁体   English   中英

调用reloadData后出现UITableView性能问题

[英]UITableView performance issue after calling reloadData

我是一名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之外还有更好的方法来重新加载数据? 任何帮助将不胜感激。 我现在花了几个小时调试和谷歌搜索,我还没有提出解决方案。

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

尝试改变这个:

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

对此:

data = sortedArray;

对于大型操作,您应该使用后台队列,而不是在主队列上执行该操作并阻止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];
    });
});

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM