Пользовательская ячейка UITableView очень медленная

У меня есть UITableView, и я создал пользовательскую ячейку для отображения своей таблицы. У меня отображается 6 UILables, и хотя у меня есть только 20 записей для отображения, прокрутка происходит очень медленно.

Вот как выглядит мой - tableView:cellForRowAtIndexPath::

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

Причина такой медленной прокрутки связана со всеми вещами, которые я здесь делаю (NSDateFormatter, CGMakeRect, floatToStringFormat...), или что-то не так с повторным использованием ячеек?

floatToStringFormat — это функция для форматирования числа до 4 знаков после запятой:

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

person CristiC    schedule 24.01.2011    source источник


Ответы (5)


Создание и настройка объектов форматирования — действительно дорогостоящая операция, поэтому я бы начал с повторного использования ваших объектов форматирования, поскольку они одинаковы при каждом вызове функции. Так что либо сделайте их статическими переменными, либо мгновенными переменными в вашем классе источника данных и создайте следующим образом:

//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];
...
person Vladimir    schedule 24.01.2011

Во-первых, вы используете два разных идентификатора: CustomCellIdentifier и BanciHistoryCellIdentifier.

Во-вторых, вам действительно нужно делать все после NSArray *object; каждый раз, когда отображается новая ячейка? Потому что, если вы этого не сделаете, вы должны переместить его в блок if (cell == nil) {.

person fabian789    schedule 24.01.2011
comment
На самом деле настоящим является BanciHistoryCellIdentifier, но я переименовал его здесь, чтобы он был CustomCellIdentifier, чтобы быть более понятным для вас, и этот избежал переименования. - person CristiC; 24.01.2011

По моему опыту, рисование ячеек табличного представления значительно замедляется, если у вас есть три или более подвидов (хотя это также зависит от устройства и представлений). Попробуйте напрямую рисовать содержимое в drawRect: вместо использования подпредставлений это должно ускорить процесс.

person Robin    schedule 24.01.2011

Что ты здесь делаешь:

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

Прочтите документацию о том, как это сделать правильно. Во-вторых, если преобразование дат и чисел в строки занимает слишком много времени, вместо этого сохраните строковые значения и превратите их в значения, когда вам нужно их изменить.

person Rich    schedule 24.01.2011

У вас установлен CellIdentifier в конструкторе интерфейсов? Он должен точно соответствовать тому, что вы используете в коде. Установите точку останова, где он загружает ячейку из пера, и убедитесь, что он повторно использует ячейки при прокрутке.

person Kendall Helmstetter Gelner    schedule 24.01.2011