2010-01-10 1 views
2

Я пытаюсь улучшить производительность прокрутки в нашем приложении. Я следовал всем общепринятым советам (нарисуйте его сами с помощью CG, ячейка непрозрачна, не имеет никаких подзонов и т. Д.), Но она по-прежнему заикается, когда у нас есть фоновый процессор и сетевая активность.Использование CGLayer для ячеек кэша в UITableView

Одно из решений указано здесь:

http://www.fieryrobot.com/blog/2008/10/08/more-glassy-scrolling-with-uitableview/

является кэширование растровых снимков ячеек, которые мы пробовали. Но растровые изображения были нечеткими и занимали тонну памяти (~ несколько сотен kb каждый).

Одно из предложений в комментариях к этой ссылке - кешировать ячейки с помощью CGLayer или CALayer (?), Потому что они идут в память графической карты. Итак, несколько вопросов,

1) Пробовал ли это? Образец кода?

2) Сколько памяти имеет графическая карта для iphone/ipod touch? Есть ли в этом смысл?

3) Любые другие предложения по ускорению?


Более подробная информация

Я использовал сэмплер процессора (по телефону) и систематически уничтожал вещи из клетки, чтобы выяснить проблему. Несколько вещей:

1) Это не настройка ячейки. Если я удаляю только призывы рисования (drawinrect и т. Д.), Но оставьте настройку, она стекловидная.

2) Это не рисунок наименьшего изображения (25x25 png), если я положил его в это хорошо.

3) Если я добавляю второе или третье изображение (первый - большой фон 320x1004kB, другой - изображение кнопки 61x35 4kB), он заикается. Я захватываю оба UIImages в методе класса, поэтому он кэшируется.

4) Текст также является проблемой. Похоже, что drawRect тратит 75% своего времени в трех методах drawNRect NSString, которые я использую. Вроде:

[mytext drawInRect: drawrect withFont: myFont lineBreakMode: UILineBreakModeTailTruncation];

Эти вызовы, похоже, проходят через веб-сайт, возможно, это вызывает некоторые из заиканий? Мне нужно иметь возможность форматировать две строки текста и один небольшой абзац текста. Мне нужно усечь текст с эллипсами. Могу ли я выполнять их из критического пути и кэшировать их? Могу ли я сделать эту часть со слоем?

ответ

0

Прежде чем вы перейдете слишком глубоко к оптимизации, используете ли вы механизм повторного использования ячеек ([tableView dequeueReusableCellWithIdentifier:]) для создания UITableViewCell s в вашем делете tableView:cellForRowAtIndexPath:?

Кроме того, вы запускаете код в Симуляторе с помощью Activity Activity Monitor? Установите интервал в 1 мс (я нашел значение по умолчанию - 10 мс - слишком большое для этого) и посмотрим, где большая часть вашего времени тратится при прокрутке.

+0

Я добавил дополнительную информацию в исходное сообщение, чтобы задать этот вопрос. Все-таки должен быть какой-то способ кэшировать ячейки в разумном объеме памяти? –

+0

На самом деле решения, с которыми вы связаны, немного экстремальны, и большинство разработчиков iPhone используют основные механизмы повторного использования ячеек, оставляя чертеж на самом устройстве. Если бы вы могли опубликовать свой (разделенный) 'tableView: cellForRowAtIndexPath:', было бы полезно - мы должны начать с начала, прежде чем перейти к производительности рисования. –

+0

Я использую метод повторного использования, проблема, похоже, не существует, поскольку я могу выполнить все повторное использование и настройку ячейки, но если я ничего не рисую, производительность будет прекрасной. Я фактически зашел так далеко, чтобы кэшировать ячейки самостоятельно, поэтому мне не нужно даже настраивать данные для них, но это не узкое место. –

4

CGLayers не кэшируются на графическом процессоре, они используются в процессе рисования элементов Core Graphics в контексте. У CALayers есть свое визуальное содержимое, кэшированное на GPU.Это может «скрыть» часть вашего использования памяти, но вы все равно столкнетесь с проблемами памяти, если будете придерживаться большого количества CALayers.

Честно говоря, если вы следовали лучшим методам работы с таблицами, описанным Лорен Брихтер и другими, о том, как рисовать весь ваш контент с помощью Core Graphics на одном уровне, делая вашу ячейку непрозрачной и подчиняя механизм повторного использования ячейки в представлении таблицы вы не можете сделать больше. Перегрузка процессора на iPhone вызовет заикание вашей прокрутки, независимо от того, насколько оптимизирован ее способ. Инерционная анимация прокрутки требует некоторой мощности процессора.

Последнее, что нужно сделать, это то, что фоновый процессор и сетевые процессы, на которые вы ссылаетесь, действительно работают на фоновом потоке. Все, что работает в основном потоке, заставит ваши методы взаимодействия приостанавливаться во время обработки этой задачи, что потенциально может привести к изменчивости вашей прокрутки.

+0

Да, все сети проходят через очереди операций, и мы использовали инструменты для устранения любых сетевых вызовов в основном потоке. Это довольно неприятно, потому что мы хотим как можно быстрее загружать файлы, но наши пользователи жалуются на прокрутку (конечно же, на 3G-сетях это нормально!) –

+0

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

+1

Вы можете сделать весь чертеж кварца, который вы делаете сейчас, для своего подкласса UITableViewCell в CALayer путем его подклассификации и размещения кода чертежа в -renderInContext: или поместив код в метод -drawLayer-in: Context :. Затем CALayer может быть сгенерирован по мере необходимости, сохранен в NSMutableDictionary и получен для каждой строки, поскольку он должен отображаться (при этом ключ словаря является номером строки). Чтобы отобразить его, вам нужно добавить слой в качестве подуровня UITableViewCell, который будет использоваться для строки. –