我是一名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
以外的数据?任何帮助将不胜感激。我现在花了几个小时调试和谷歌搜索,我还没有提出解决方案。
答案 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的内存。因此,当用户选择按特定列排序时,您已经对数据进行了排序,并且您只需交换用作数据源的数组。对于用户来说,那么分类几乎是瞬间出现的。