Есть ли причина, по которой мы просто не объявляем cellForRowAtIndexPath следующим образом:

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell * cell = [self.tableView cellForRowAtIndexPath:indexPath];
    return cell.bounds.size.height;
}

В чем будет недостаток?

Я изменил это с

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell * cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
    return cell.bounds.size.height;
}

person user4234    schedule 04.12.2012    source источник
comment
Я не думаю, что первый является допустимым синтаксисом Objective-C.   -  person Hot Licks    schedule 04.12.2012
comment
(И я не уверен, что любой из них является хорошей идеей.)   -  person Hot Licks    schedule 04.12.2012
comment
Какое отношение этот вопрос имеет к объявлению метода tableView:cellForRowAtIndexPath:?   -  person rmaddy    schedule 04.12.2012
comment
@HotLicks Первый в порядке (синтаксически). UITableView имеет метод прямого получения такой ячейки.   -  person rmaddy    schedule 04.12.2012
comment
@rmaddy - хорошо, это имеет смысл - два разных метода для разных классов. На первый взгляд кажется, что OP пытается смешать синтаксис свойства с синтаксисом вызова обычного метода.   -  person Hot Licks    schedule 04.12.2012
comment
Также см. вопросы/12652761/.   -  person Martin R    schedule 04.12.2012


Ответы (2)


Как указывает rmaddy, вы не можете использовать первую версию, потому что -[UITableView cellForRowAtIndexPath:] может привести к тому, что табличное представление снова отправит вам tableView:heightForRowAtIndexPath:, что приведет к бесконечной рекурсии.

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

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

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    @autoreleasepool {
        UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
        return cell.bounds.size.height;
    }
}
person rob mayoff    schedule 04.12.2012

Обычно вы хотите получить ячейку из таблицы, как в 1-м бите кода. Но в этом случае нельзя. Если вы попытаетесь, вы получите рекурсивный вызов между cellForRowAtIndexPath и heightForRowAtIndexPath.

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

person rmaddy    schedule 04.12.2012
comment
Как указал Роб, когда вы запрашиваете у таблицы ячейку, таблица сначала пытается получить высоту ячейки. Когда он пытается получить высоту, вы запрашиваете ячейку у таблицы. Это продолжается до тех пор, пока стек не переполнится и приложение не вылетит. - person rmaddy; 04.12.2012
comment
@SharenEayrs Метод cellForRowAtIndexPath возвращает ячейку, если строка видна, и ноль, если строка не видна. Чтобы выяснить, какие строки видны, табличное представление должно знать высоту каждой ячейки. - person rob mayoff; 04.12.2012
comment
Это кажется довольно глупым. Почему ему нужно сначала знать высоту ячейки, прежде чем узнать, видна ли она? Он может запрашивать строку, которая может быть видимой, вычислять высоту и переходить к следующей строке и так далее. - person user4234; 04.12.2012