2010-12-07 5 views
13

Просто нашел очень странное и неожиданное поведение в классе UITableView. Мне нужна последняя ячейка таблицы в моей секции, чтобы быть разной высотой от других клеток, так что я делаю в основном это:Calling numberOfRowsInSection: from heightForRowAtIndexPath

- (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:, он вызывает мой метод tableView: numberOfRowsInSection: источника данных. Это имеет смысл, поскольку метод tableView возвращает кешированную версию значения источника данных, поэтому ему необходимо сначала получить значение из источника данных. Но тогда он вызывает heightForRowAtIndexPath, передавая ему indexPath [0, 0] снова! И он делает это без остановок.

я смог обойти его, используя

[self tableView:tableView numberOfRowsInSection:indexPath.section] 

вместо (называя свой метод источника данных вместо метода Tableview в). У кого-нибудь есть идея, почему он это делает? Это определенное поведение? Или ошибка в структуре TableView Apple?

+0

Кажется, что внутренняя обработка Apple. Думаю, нам понадобится инженер Apple, чтобы ответить на этот вопрос. – Altealice 2010-12-08 04:02:07

+0

не должны ли они плавать 44,0 и 88,0? – railwayparade 2011-01-11 10:09:43

ответ

17

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

Вы неправильно понимаете макет M-V-C, на котором Apple использует свои элементы управления. Ответ на высоту строки должен исходить из вашей модели, а не от вызова назад к классу вида. Это заставляет класс представления запрашивать дополнительную информацию (для создания внутреннего кеша), который запускает набор рекурсивных вызовов.

Убедитесь, что все методы делегатов datasource возвращают данные из вашей модели и не полагаются на кеширование чего-либо. Если вы отлаживаете какое-либо представление на основе данных, вы будете удивлены, сколько раз UITableView запрашивает данные. Но именно так Apple закодировала это.

Смежные вопросы