Медленная загрузка таблицы - PullRequest
2 голосов
/ 03 апреля 2012

У меня проблема со временем загрузки таблицы, как я могу это улучшить?Загрузка таблицы занимает около 25-30 секунд и занимает около 25-30 секунд.У меня есть около 130000 строк в моей базе данных sqlite, и я использую основные данные для доступа к этим данным.

Любая помощь или предложения будут с благодарностью.

Спасибо за ваше время, и если вам нужна дополнительная информация, пожалуйста, дайте мне знать.

Две вещи, которые япытался оптимизировать.

+ Базовые данные - возможно, моя выборка данных может быть улучшена, но я не знаю, что еще я могу сделать, код указанниже.

if (fetchedResultsController != nil) 
{
    return fetchedResultsController;
}

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription 
                               entityForName:@"DataModel" inManagedObjectContext:_context];
[fetchRequest setEntity:entity];

NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"subsection" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

//[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"section == [c] %@ AND area == 'Tables'", tablesSection]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"area == 'Tables'"]];

[fetchRequest setFetchBatchSize:100];
//[fetchRequest setFetchLimit:100];
[fetchRequest setFetchOffset:10];

NSFetchedResultsController *theFetchedResultsController = 
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_context sectionNameKeyPath:@"uppercaseFirstLetterOfNameTables" cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
fetchedResultsController.delegate = self;

return fetchedResultsController;    

+ Представление таблицы , я думаю, что способ загрузки данных, вероятно, является главной проблемой здесь.Я динамически вычисляю высоту для каждой ячейки, и я думаю, что это замедляет процесс. Если я удаляю код для метода heightForRowAtIndexPath , я могу уменьшить время загрузки до 8 секунд.

(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Model *info;
    if(self.searchDisplayController.isActive)
    {
        info = [searchFetchedResultsController objectAtIndexPath:indexPath];
    }
    else
    {
        info = [fetchedResultsController objectAtIndexPath:indexPath];
    }
    NSString *subsectionHeight = info.subsection;
    NSString *textHeight = info.text;
    CGSize titleSize = [subsectionHeight sizeWithFont:[UIFont fontWithName:@"Helvetica-Bold" size:20] constrainedToSize:CGSizeMake(300, MAXFLOAT) lineBreakMode:UILineBreakModeWordWrap];
    CGSize detailSize = [textHeight sizeWithFont:[UIFont fontWithName:@"Helvetica-Bold" size:16] constrainedToSize:CGSizeMake(300, MAXFLOAT) lineBreakMode:UILineBreakModeWordWrap];

    return detailSize.height+titleSize.height;

    //return 88;
}



 (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
        cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
        cell.textLabel.numberOfLines = 0;
        cell.detailTextLabel.numberOfLines = 0;
    }
    //if-statement need to prevent search index issue
    if(self.searchDisplayController.isActive && [self.searchDisplayController.searchBar.text isEqualToString:@""])
    {
        return cell;
    }
    // Configure the cell...
    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

 (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{
    Model *info;
    if (self.searchDisplayController.isActive)
    {
        info = [searchFetchedResultsController objectAtIndexPath:indexPath];
    }
    else
    {
        info = [fetchedResultsController objectAtIndexPath:indexPath];
    }
    cell.textLabel.text = info.subsection;
    cell.detailTextLabel.text = info.text;

}

ОБНОВЛЕНИЕ : я использую решение с закомментированной heightForRowAtIndexPath, но мне нужна помощь с оптимизацией поиска, может кто-нибудь помочь мне понять, как реализовать решение в сеансе WWDC 2010?Не понимаю, как создать новую часть сущности, например, нужно ли мне заполнять эту новую сущность данными?

Ответы [ 3 ]

1 голос
/ 03 апреля 2012

Вы должны разбить страницу на страницы: вставьте кнопку, которая показывает больше результатов в конце таблицы (я не могу представить, как я прокручиваю себя на 9000 строк)

0 голосов
/ 23 февраля 2013

Если все, что вам нужно для заполнения UITableViewCell, это атрибуты «текст» и «подраздел», то вы можете разделить основную таблицу в одну таблицу, которая имеет только эти 2 атрибута и, возможно, ключевое поле, и поместить все остальные атрибуты в другой. стол, связанный один на один. Если все записи будут считаны в память (что не должно происходить нормально, когда вы запускаете UITableview), тогда, если таблица будет меньше, потребуется гораздо меньше времени (т. Е. Содержит только несколько столбцов). Я переместил поле изображения со своей основной таблицы, оставив в основной таблице около 5 полей и 5 связей, и у меня не было проблем с 150 000 записей на iPad 2.

Но вы должны проверять, что на самом деле происходит, регистрируя фактические операторы SQL, используемые Core Data (передавая -com.apple.CoreData.SQLDebug 1 в качестве параметра при запуске).

Если ваше приложение ведет себя хорошо, только показанные записи должны запускать метод heightForRowAtIndexPath. Так что не 130.000 раз, а макс. 10 раз, чтобы показать первые результаты. Так что это обычно не должно быть вашей проблемой.

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

0 голосов
/ 03 апреля 2012

Вам определенно не нужно вызывать heightForRowAtIndexPath 9000 раз, просто установите высоту в IB на нужную вам высоту и уберите этот метод.8 секунд для 9000 записей на самом деле не так уж и плохо.

9000 записей - это много для обработки TableView.Есть ли в любом случае вы можете уменьшить это #?

...