Вызов numberOfRowsInSection: from heightForRowAtIndexPath
Просто нашел очень странное и неожиданное поведение в классе UITableView. Мне нужна последняя ячейка таблицы в моем разделе, чтобы быть другой высотой из других ячеек, поэтому я делаю в основном это:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section] - 1)
return 44;
else
return 88; //double size for all but the last row
}
Кажется довольно прямолинейным, но когда я запускаю его, я получаю бесконечный цикл, и он падает. Я решил, что когда я звоню numberOfRowsInSection:
, он вызывает мой метод datasource tableView: numberOfRowsInSection:
. Это имеет смысл, поскольку метод tableView возвращает кешированную версию значения источника данных, поэтому ему необходимо сначала получить значение из источника данных. Но тогда он вызывает heightForRowAtIndexPath, передавая ему indexPath [0, 0] снова! И он делает это без остановок.
Мне удалось обойти это, используя
[self tableView:tableView numberOfRowsInSection:indexPath.section]
вместо этого (вызов метода datasource вместо метода tableView). У кого-нибудь есть идея, почему он это делает? Это определенное поведение? Или ошибка в структуре Apple TableView?
Ответы
Ответ 1
Проблема в том, что UITableView запрашивает ваш источник данных для данных, и вы говорите, что ответ зависит от данных, которые он может или не может кэшировать.
Вы неправильно понимаете макет M-V-C, на котором Apple использует свои элементы управления. Ответ на высоту строки должен исходить из вашей модели, а не от вызова назад к классу вида. Это заставляет класс представления запрашивать дополнительную информацию (для создания внутреннего кеша), который запускает набор рекурсивных вызовов.
Убедитесь, что все методы делегатов datasource возвращают данные из вашей модели и не полагаются на кеширование чего-либо. Если вы отлаживаете какое-либо представление на основе данных, вы будете удивлены, сколько раз UITableView запрашивает данные. Но то, как Apple закодировала его.