Динамическая высота UITableView с объектами Core Data

Последние несколько дней я пытался разгадать загадку, почему мой NSFetchedResultsController с размером пакета 20 всегда выдавал ошибку (то есть загружал в память) все мои объекты сразу после завершения выборки, вызывая запрос занять ~ 20 секунд.

Оказывается, это было потому, что в моем heightForRowAtIndexPath высота была основана на длине свойства NSString каждого извлеченного объекта, и поэтому при перезагрузке таблицы, если в таблице 2000 строк, высота вычисляется для каждой строки в в самом начале, и поскольку я получаю доступ к текстовому свойству объекта, он выдаст ошибку в 2000 объектах (в пакетах по 20 размеров) в самом начале, что приведет к тому, что это займет вечность. (Я не знал, что высота строк рассчитывалась с самого начала).

Итак, вопрос в том, что если у меня есть контроллер результатов выборки с размером пакета 20, но мои высоты строк основаны на текстовом свойстве объекта, что, если я попытаюсь получить доступ, приведет к тому, что объект больше не будет ошибкой, а на самом деле загружается в память, что может быть обходным путем для вычисления высоты?

Каковы мои варианты?


person Snowman    schedule 23.06.2012    source источник
comment
Что произойдет, если вы проверите, является ли объект ошибкой, если это так, вернете произвольный размер, иначе получите строку и вычислите? Вызывается ли метод снова, когда ячейка появляется для просмотра? Я просто предполагаю здесь. Это или реализация ленивой загрузки (т.е. новые строки добавляются при прокрутке), кажутся вашими единственными вариантами.   -  person jrturton    schedule 23.06.2012
comment
No heightForRow вызывается только в начале перезагрузки и не вызывается каждый раз, когда появляется ячейка (как это делал бы cellForRow). Я тоже так думал, но не думаю, что это сработает..   -  person Snowman    schedule 23.06.2012


Ответы (2)


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

Мябе могут быть и другие ценные решения.

person Lorenzo B    schedule 23.06.2012
comment
Но мне все равно нужно получить доступ к этому целочисленному свойству, что приведет к тому, что объект больше не будет ошибкой и будет загружен в память. - person Snowman; 23.06.2012
comment
@mohabitar Это не совсем так. Если вы предварительно выбираете это свойство в своем запросе на выборку, а затем получаете к нему доступ, текст строки не загружается в память до тех пор, пока вы не потребуете его, в противном случае свойство text останется ошибкой. - person Lorenzo B; 23.06.2012
comment
Верно, но когда я получаю доступ к свойству строки, объект, содержащий строку, загружается в память (поскольку раньше это была ошибка, не конкретизированная). - person Snowman; 23.06.2012
comment
@mohabitar Вам нужно рассчитать эту высоту, прежде чем отображать данные в табличном представлении. В другой момент жизненного цикла вашего приложения. Например, когда вы вставляете объекты. - person Lorenzo B; 23.06.2012
comment
Да, я понимаю, но я думаю, что вы все еще упускаете из виду главное: размер моего пакета выборки составляет 20. Из 2000 объектов 1985 из них будут неисправными, что означает, что ни одно из их свойств еще не создано. Чтобы вычислить высоту, мне нужно знать содержимое свойства объекта, и доступ к этому свойству приводит к тому, что объект больше не является ошибкой. Думаю, я могу создать еще один запрос на выборку, который просто извлекает текстовое свойство без ограничения размера пакета. - person Snowman; 23.06.2012

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

person Stavash    schedule 23.06.2012
comment
Верно, но как метод узнает, что такое NSString, не создавая экземпляры объектов? NSString является свойством объекта, и если объект является ошибкой, вызов object.textProperty вызывает загрузку объекта в память. - person Snowman; 23.06.2012
comment
Эта проблема связана с вашей реализацией. Может быть, обходной путь для получения этих строк без создания экземпляров? Это курица и яйцо :) - person Stavash; 23.06.2012