简体   繁体   中英

UITableView performance issue after calling reloadData

I'm an Android developer working on my first iOS project. I have a UITableView that displays almost 37,500 rows. One row for each item in an grocery store. The list has 3 columns one containing the item name and the other 2 containing other important data. The columns are sortable, and to handle the sorting I sort the data array as I need to and call [tableView reloadData] after I'm done sorting the array. This works fine except there is a long delay of at least a few seconds after reloading the data where the main thread is locked up doing work. I'm no stranger to list performance as I've had to make smooth lists numerous times in Android. So from what I can tell I'm not really doing much to cause this. The only thing I can think of is just the large number of items in my array. Here is the relevant code:

Here are the table methods I am overriding:

-(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];
}

Here is the method I use to sort the array:

-(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];
}

I do not have any performance issues until after calling [self.tableView reloadData] . So I'm wondering if there is something I'm missing, or is there maybe a better way of reloading the data besides reloadData ? Any help will be greatly appreciated. I've spent a few hours now debugging and Googling and I haven't come up with a solution yet.

One possible cause of your UI hanging is that you're removing and adding all 37.5k objects between two arrays.

Try changing this:

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

to this:

data = sortedArray;

For a large operation you should use a background queue, rather performing that on main queue and blocking UI. You could call reloadData on the main queue after data becomes available from the background operation:

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

Also consider using Paul's suggestion, as from the previous answer.

Your code looks good. Like @paulrehkugler says in his answer, you can just do data = sortedArray where you sort the array.

With the amount of data you have, consider pre-sorting your data in a background thread. By my calculations, with 37,500 objects it would take 150K of memory if you keep around 3 arrays with different sort orders. So when the user chooses to sort by a particular column, you'd already have the data sorted, and you'd just swap the array that is used as the data source. For the user, sorting then would appear practically instantaneous.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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