문제

I have a UITableView and I have created a custom cell to display my table. I have 6 UILables displayed and although I have only 20 records to show, it is very slow when I scroll.

This is how my - tableView: cellForRowAtIndexPath: looks like:

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

    static NSString *CustomCellIdentifier = @"CustomCellIdentifier";

    HistoryCell *cell = (HistoryCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];

    if (cell == nil) { 
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"HistoryCell" owner:nil options:nil];

        for (id oneObject in nib)
            if ([oneObject isKindOfClass:[UITableViewCell class]])
                cell = (HistoryCell *) oneObject;
    }

    NSArray *object;
    object = [cours objectForKey: [NSString stringWithFormat:@"%d", indexPath.section]];
    History *rowData = [object objectAtIndex:indexPath.row];

    if (rowData.month == 99) {
        cell.hour.frame = CGRectMake(10, 0, 135, 35);
        cell.data.hidden = YES;
        cell.hour.textColor = [UIColor blackColor];
        cell.hour.font = [UIFont fontWithName:@"Verdana" size:17];
    } else {
        cell.data.hidden = NO;
        cell.hour.frame = CGRectMake(10, 16, 135, 19);
        cell.hour.textColor = [UIColor grayColor];
        cell.hour.font = [UIFont fontWithName:@"Verdana" size:12];
    }

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"d (EEEE)"];
    [formatter setLocale:self.selectedLanguageLocale];
    NSString *stringFromDate = [formatter stringFromDate:rowData.data];
    [formatter release];

    cell.data.text = stringFromDate;
    cell.hour.text = rowData.ora;

    float Var1  = [rowData.Var2 floatValue];
    float Var2  = [rowData.Var2 floatValue];

    cell.R1.text = [self floatToStringFormat: [rowData.R1 floatValue]];
    cell.R2.text = [self floatToStringFormat: [rowData.R2 floatValue]];

    if (Var1 <= 0) {
        cell.Var1.textColor = [UIColor greenColor];
    } else {
        cell.Var1.textColor = [UIColor redColor];
    }
    if (Var2 <= 0) {
        cell.Var2.textColor = [UIColor greenColor];
    } else {
        cell.Var2.textColor = [UIColor redColor];
    }
    cell.Var1.text = [self floatToStringFormat:Var1];
    cell.Var2.text = [self floatToStringFormat:Var2];

    cell.selectionStyle = UITableViewCellSelectionStyleGray;
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}

The reason for running that slow on scroll is because of all the things I am doing here (NSDateFormatter, CGMakeRect, floatToStringFormat...) or is there something wrong with reusing cells?

floatToStringFormat is a function to format a number to 4 decimals:

- (NSString *)floatToStringFormat:(float)number{
    NSNumberFormatter *myFloat = [[NSNumberFormatter alloc] init]; 
    [myFloat setFormatterBehavior:NSNumberFormatterBehavior10_4]; 
    [myFloat setNumberStyle:NSNumberFormatterDecimalStyle];
    [myFloat setRoundingMode:NSNumberFormatterRoundHalfUp];
    [myFloat setMinimumFractionDigits:4];
    [myFloat setMaximumFractionDigits:4];
    NSString *res = [myFloat stringFromNumber:[NSNumber numberWithFloat:number]];
    [myFloat release];
    return res;
}
도움이 되었습니까?

해결책

Creating and setting up formatter objects is an expensive operation indeed, so I'd start with reusing your formatter objects since they are the same on each function call. So either make them static variables or instant variables in your data source class and create the following way:

//static variable case
NSDateFormatter *formatter = nil;
if (!formatter){
   formatter = [[NSDateFormatter alloc] init];
   [formatter setDateFormat:@"d (EEEE)"];
   [formatter setLocale:self.selectedLanguageLocale];
}
NSString *stringFromDate = [formatter stringFromDate:rowData.data];
...

다른 팁

Firstly, you are using two different identifiers: CustomCellIdentifier and BanciHistoryCellIdentifier.

Secondly, do you really need to do everything after NSArray *object; every time a new cell is displayed? Because if you don't, you should move it to the if (cell == nil) { block.

From my experience the drawing of table view cells is significantly slowed down if you have three or more subviews (also depends on the device and the views though). Try to directly draw the content in drawRect: instead of using subviews, this should speed things up.

What are you doing here:

if (cell == nil) { 
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"HistoryCell" owner:nil options:nil];

        for (id oneObject in nib)
            if ([oneObject isKindOfClass:[UITableViewCell class]])
                cell = (HistoryCell *) oneObject;
    }

Go read the documentation on how to do this properly. Secondly, if this is taking too long to convert the dates and numbers to strings then store the string values instead, and turn them into values when you need to modify them.

Do you have the CellIdentifier set in Interface builder? It must match exactly what you are using in code. Set a breakpoint where it loads the cell from the nib and make sure it's reusing cells when you scroll.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top