Подтвердить что ты не робот

UITableView dequeueReusableCellWithIdentifier Theory

Когда яблоко разработало UITableView для первого iPhone, у них была проблема с производительностью при прокрутке. Затем один умный инженер обнаружил, что причиной этого было то, что распределение объектов происходит с ценой, поэтому он придумал способ повторного использования ячеек.

"Распределение объектов имеет стоимость исполнения, особенно если распределение должно происходить повторно за короткий период, например, когда Пользователь прокручивает табличный вид. Если вы повторно используете ячейки вместо выделения новые, вы значительно улучшаете производительность настольных представлений".

Источник: справочная библиотека iOS

Повторное использование используемой ячейки:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

Теперь, что мне интересно, что на самом деле происходит здесь? Он выглядит в TableView, если есть ячейка с этим идентификатором и просто возвращает ее? Ну, да, но если он отправляет ссылку вместо выделения, и у меня есть табличное представление, пусть скажем, что 4 ячейки с тем же идентификатором все видимы. Как он может умножаться на четыре экземпляра без выделения?

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

Моя собственная теория состоит в том, что она выделяет четыре ячейки (просто потому, что она тоже). Когда ячейка исчезает с экрана, она будет помещена в очередь повторного использования TableView. Когда нужна новая ячейка, она смотрит в очередь, если ячейка с тем же идентификатором доступна, она вызывает метод prepareForReuse в этой ячейке и удаляет себя из очереди.

4b9b3361

Ответ 1

dequeueReusableCellWithIdentifier: возвращает только cell, если он был помечен как готовый для повторного использования. Вот почему почти в каждом методе cellForRowAtIndexPath: вы увидите что-то вроде



UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (nil == cell) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                   reuseIdentifier:CellIdentifier];
}

// Do something to cell

return cell;

По сути, для заполнения видимой части tableview (плюс один или два) будет выделено достаточно строк. В качестве cells scroll с экрана они удаляются из table и помечены как готовые для reuse. По мере увеличения очереди доступных ячеек ваша строка, запрашивающая dequeued cell, начнет получать cell для использования, после чего вам больше не придется выделять.

Ответ 2

Код deqeueueReusableCellsWithIdentifier: будет выглядеть примерно так:

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

- (UIView*) dequeueReusablePage
{
    UIView* page = [reusablePages_ anyObject];
    if (page != nil) {
        [[page retain] autorelease];
        [reusablePages_ removeObject: page];
    }
    return page;
}

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

Когда ячейки прокручивают экран и больше не видны, они помещаются в этот набор.

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

Используемые ячейки прокручиваются в верхней части экрана, помещаются в набор, а затем берутся за ячейку, которая появляется в нижней части экрана.

Ответ 3

Цель dequeueReusableCellWithIdentifier - использовать меньше памяти. если мы используем 100 ячеек в tableView, тогда вам нужно каждый раз создавать 100 ячеек. Это уменьшает функциональность приложения и может привести к сбою. Для этого dequeueReusableCellWithIdentifier инициализируйте определенное количество ячеек, которые мы создали, и ячейки снова будут использоваться для дальнейшей обработки.

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TableIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TableIdentifier];
    }

    ExternalClassTableViewCell *myCell = [[ExternalClassTableViewCell alloc]init];
    myCell.MyCellText.text = [tableData objectAtIndex:indexPath.row];
    myCell.MyCellImage.backgroundColor = [UIColor blueColor];

    return cell;
}