iPhone - использование dequeueReusableCellWithIdentifier

Я работаю над приложением для iPhone, которое имеет довольно крупный UITableView с данными, взятыми от сети, таким образом, я пытаюсь оптимизировать ее создание и использование.

Я узнал это dequeueReusableCellWithIdentifier довольно полезно, но после наблюдения многих исходных кодов с помощью этого, я задаюсь вопросом, является ли использование, которое я делаю из этой функции, хорошим.

Вот то, что обычно делают люди:

UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

if (cell == nil) {
  cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"];

// Add elements to the cell
return cell;

И вот способ, которым я сделал это:

// The cell row
NSString identifier = [NSString stringWithFormat:@"Cell %d", indexPath.row]; 

UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:identifier];

if (cell != nil)
  return cell;

cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:identifier];
// Add elements to the cell
return cell;

Различие - то, что люди используют тот же идентификатор для каждой ячейки, так исключение из очереди одного единственного избегает к выделению нового.

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

В штрафе я не знаю, который является лучшим, "общий" метод перекрывает использование памяти таблицы к точному количеству ячеек, которые это отображает, пока метод, который я использую, кажется, способствует скорости, поскольку это сохраняет все расчетные ячейки, но может вызвать потребление памяти большой емкости (если нет внутренний предел очереди).

Разве я неправ использовать его этот путь? Или это только до разработчика, в зависимости от его потребностей?

61
задан Simple Maurya 22 August 2018 в 09:15
поделиться

3 ответа

Назначение dequeueReusableCellWithIdentifier - использовать меньше памяти. Если на экране может поместиться 4 или 5 ячеек таблицы, то при повторном использовании вам нужно всего лишь 4 или 5 ячеек таблицы, выделенных в памяти, даже если таблица имеет 1000 записей.

Во втором способе повторного использования нет. У второго способа нет преимущества перед простым использованием массива ячеек таблицы. Если в вашей таблице 1000 записей, то в памяти будет выделено 1000 ячеек. Если вы собираетесь это сделать, вы должны поместить их в массив и просто проиндексировать массив с номером строки и вернуть ячейку. Для небольших таблиц с фиксированными ячейками это может быть разумным решением, для динамических или больших таблиц это не лучшая идея.

70
ответ дан 24 November 2019 в 17:18
поделиться

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

4
ответ дан 24 November 2019 в 17:18
поделиться

Что касается идентификатора ячейки. Вместо того, чтобы использовать просто "cell" для идентификатора, и вместо уникального идентификатора, как в OP, вы могли бы использовать "type-identifier"? Например, если в моей таблице есть 3 типа ячеек - одна с очень сложным подмакетом, одна только с Style1, и одна с Style2, я должен определить эти три отдельно и затем просто перестроить их, если dequeue приходит к nil.

Например:

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
    NSString* ident = @"";
    if(indexPath.section == 0) ident= @"complicated";
    if(indexPath.section == 1) ident= @"style1";
    if(indexPath.section == 2) ident = @"style2";

    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:ident];

    if(cell == nil){

       if(ident == @"complicated"){
          cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:ident] autorelease]; 
         // do excessive subview building
       }
       if(ident == @"style1"){
          cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyle1 reuseIdentifier:ident] autorelease]; 
       }

       if(ident == @"style2"){
          cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyle2 reuseIdentifier:ident] autorelease]; 
       }


    }
    if(ident == @"complicated"){
       // change the text/etc (unique values) of our many subviews
    }
    if(ident == @"style1"){
      [[cell textLabel] setText:@"Whatever"];
    }
    if(ident == @"style2"){
      [[cell textLabel] setText:@"Whateverelse"];
    }

    return cell; 
}

(Этот код, вероятно, не будет выполняться, потому что я написал его здесь, но, надеюсь, вы поняли идею. )

Я не думаю, что Apple создала бы всю идею многоразовых ячеек с идентификаторами, если бы они хотели, чтобы все идентификаторы были "cell", не так ли?

19
ответ дан 24 November 2019 в 17:18
поделиться