Использование CGLayer для кэширования ячеек в UITableView
Я пытаюсь улучшить производительность прокрутки в нашем приложении. Я следовал всем общепринятым советам (нарисуйте его самостоятельно с помощью CG, ячейка непрозрачна, нет подпредставлений и т. Д.), Но иногда он все еще заикается, когда у нас есть фоновая загрузка ЦП и сети.
Одно решение заявлено здесь:
http://www.fieryrobot.com/blog/2008/10/08/more-glassy-scrolling-with-uitableview/
кешировать растровые снимки ячеек, которые мы пробовали. Но растровые изображения были нечеткими и занимали тонну памяти (~ несколько сотен килобайт каждый).
Одно из предложений в комментариях к этой ссылке - кэшировать ячейки с помощью CGLayer или CALayer(?), Потому что они попадают в память графической карты. Итак, несколько вопросов,
1) Кто-нибудь пробовал это? Образец кода?
2) Сколько памяти имеет графическая карта iphone/ipod touch? Есть ли в этом смысл?
3) Есть ли другие предложения по ускорению?
Дополнительная информация
Я использовал сэмплер процессора (на телефоне) и систематически удалял вещи из клетки, чтобы выяснить проблему. Несколько вещей:
1) Это не настройка ячейки. Если я удаляю только вызовы рисования (drawinrect и т. Д.), Но оставляю настройку, это стекло
2) Это не рисунок самого маленького изображения (25x25 png), если я положу это хорошо.
3) Если я добавлю второе или третье изображение (первое - это большой фон 320x1004kB, другое - изображение кнопки 61x35 4kB), оно заикается. Я беру оба UIImages в методе класса, поэтому он кэшируется.
4) Текст тоже проблема. Похоже, что drawRect тратит 75% своего времени в трех методах NSString drawInRect, которые я использую. Подобно:
[mytext drawInRect: drawrect withFont: myFont lineBreakMode: UILineBreakModeTailTruncation];
Эти звонки, кажется, проходят через webcore, возможно, это вызывает некоторые заикания? Мне нужно уметь форматировать две строки текста и один маленький абзац текста. Мне нужна возможность обрезать текст с помощью эллипсов. Могу ли я выполнить это из критического пути и кэшировать их? Могу ли я сделать эту часть со слоем?
2 ответа
CGLayers не кэшируются на GPU, они используются во время рисования элементов Core Graphics в контексте. CALayers хранят визуальное содержимое в графическом процессоре. Это может "скрыть" часть вашего использования памяти, но вы все равно столкнетесь с проблемами памяти, если будете держаться за большое количество CALayers.
Честно говоря, если вы следовали рекомендациям по табличному представлению, как описано Лореном Брихтером и другими, рисовать весь ваш контент с помощью Core Graphics в одном слое, сделать вашу ячейку непрозрачной и подчиняться механизму повторного использования ячейки табличного представления, там не так много, что вы можете сделать. Перегрузка процессора на iPhone вызовет заикание вашей прокрутки, независимо от того, насколько оптимизированной вы сможете это сделать. Анимация инерционной прокрутки требует некоторой мощности процессора для запуска.
И последнее, на что нужно обратить внимание: фоновые процессоры и сетевые процессы, на которые вы ссылаетесь, действительно работают в фоновом потоке. Все, что выполняется в главном потоке, заставит ваши методы взаимодействия приостановиться во время обработки этой задачи, что может повысить гибкость прокрутки.
Прежде чем вы углубитесь в оптимизацию, вы используете механизм повторного использования ячеек ([tableView dequeueReusableCellWithIdentifier:]
) для создания UITableViewCell
в вашем делегате tableView:cellForRowAtIndexPath:
?
Кроме того, вы запускали код в симуляторе с помощью монитора активности инструментов? Установите интервал в 1 мс (я нашел значение по умолчанию - 10 мс - слишком большое для этого) и посмотрите, сколько времени вы проводите при прокрутке.