Как сделать прокрутку UITableView более плавной? - PullRequest
1 голос
/ 13 сентября 2011

У меня есть таблица с примерно 20 ячейками с изображениями, которые загружаются из сети.

В данный момент при прокрутке он прерывистый, и его нужно сделать более плавным.

Мой метод:

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

    CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {

        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];

        for (id currentObject in topLevelObjects){
            if ([currentObject isKindOfClass:[UITableViewCell class]]){
                cell =  (CustomCell *) currentObject;
                break;
            }
        }
    }

    NSDictionary *article = [entriesArray objectAtIndex:[indexPath row]];
    NSString *title = [article objectForKey:@"title"];
    NSString *date = [article objectForKey:@"publishedDate"];
    NSString *dateEdited = [date substringToIndex:16];

    cell.nameLabel.text  = title;
    cell.dateLabel.text  = dateEdited;

    NSURL *myURL=[NSURL URLWithString:[self.picturesArray objectAtIndex:indexPath.row]]; 
    NSData *myData1 = [[NSData alloc] initWithContentsOfURL:myURL];
    UIImage *myImage = [[UIImage alloc] initWithData:myData1]; 

    cell.imageView.image = myImage;
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 2;

    return cell;
}

Какой совет?

Ответы [ 6 ]

2 голосов
/ 13 сентября 2011

Не похоже, что вы выполняете сетевой запрос в фоновом потоке, что вам и нужно делать.Не только с точки зрения производительности, но и с точки зрения стабильности.Что произойдет, если сервер, к которому вы отправляете сетевой запрос, не работает?Я не уверен, как initWithContentsOfURL: обрабатывает сбои, но ваш код, похоже, не проверяет сбой этого метода, поэтому похоже, что ваша программа потерпит крах в результате сетевых проблем.

Реализацияизвлечение в фоновом потоке не приведет к блокировке основного потока, что позволит прокручивать ваш UITableView гораздо более плавно, однако компромисс для этого будет то, что изображения табличного представления могут некоторое время оставаться пустыми, так как он ожидает завершения фонового потокасетевой запрос.

2 голосов
/ 13 сентября 2011

Есть несколько вопросов.Во-первых, у вас есть утечки памяти.myData1 и myImage созданы, но не выпущены.

Тем не менее, я предполагаю, что хиты высокой производительности связаны с созданием UIImage.Удалите это из этого метода запроса ячейки.Возможно, создайте кеш изображений, на которые вы сможете нарисовать.Например, создайте их как статические объекты UIImage, созданные в вашем методе initialize.

Я думаю, что это решит большую часть ваших проблем с производительностью.Одним из последних изменений будет удаление цикла for из этого метода.Возможно, создайте NSDictionary, чтобы объекты можно было искать непосредственно.

0 голосов
/ 13 сентября 2011

Вам нужно лениво загружать ваши изображения.Это означает загрузку их в другой поток.У Apple есть отличный пример кода, который демонстрирует это .

0 голосов
/ 13 сентября 2011

Первое, что я хотел бы проверить (и это легко пропустить), это убедиться, что идентификатор повторного использования вашей ячейки установлен правильно (в вашем случае это «Ячейка») в вашем файле CustomCell.xib.

Пример:

enter image description here

Для создания вашей ячейки.при условии, что у вас есть перо с именем CustomCell.xib, вы должны создать IBOutlet в вашем контроллере представления:

@ property (nonatomic, retain) IBOutlet UITableViewCell * customCell;

и затем в вашем перте CustomCellустановите владельца файла в качестве контроллера представления и подключите ячейку к специализированной ячейке владельца файла.

Чтобы создать ячейку, используйте следующий код:

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if(cell == nil)
    {
        [[NSBundle mainBundle] loadNibNamed: @"CustomCell" owner: self options: nil];
        cell = self.customCell;
        self.customCell = nil;
    }
    // Customise your cell here
    return cell;    
}
0 голосов
/ 13 сентября 2011

Это способ загрузки пользовательских ячеек

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

    CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
cell = [CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIndetifier];
    }

    NSDictionary *article = [entriesArray objectAtIndex:[indexPath row]];
    NSString *title = [article objectForKey:@"title"];
    NSString *date = [article objectForKey:@"publishedDate"];
    NSString *dateEdited = [date substringToIndex:16];

    cell.nameLabel.text  = title;
    cell.dateLabel.text  = dateEdited;

    NSURL *myURL=[NSURL URLWithString:[self.picturesArray objectAtIndex:indexPath.row]]; 
    NSData *myData1 = [[NSData alloc] initWithContentsOfURL:myURL] autorelease];
    UIImage *myImage = [[UIImage alloc] initWithData:myData1] autorelease]; 

    cell.imageView.image = myImage;
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 2;

    return [cell autorelease];
}
0 голосов
/ 13 сентября 2011

Вы не должны загружать файлы изображений в главном цикле событий.

Попробуйте использовать какой-нибудь фоновый загрузчик, например SDWebImage .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...