Чтобы прояснить цель этого вопроса: я знаю, КАК создавать сложные представления как с подпредставлениями, так и с использованием drawRect. Я пытаюсь полностью понять, когда и почему использовать один над другим.
Я также понимаю, что не имеет смысла оптимизировать это намного раньше времени и делать что-то более сложное, прежде чем выполнять профилирование. Подумайте, что мне комфортно с обоими методами, и теперь очень хочется более глубокого понимания.
Я часто путаюсь с изучением того, как сделать прокрутку табличного представления действительно плавной и быстрой. Конечно, первоначальный источник этого метода от автора за твиттер для iPhone (ранее tweetie). В основном это говорит о том, что для того, чтобы сделать скроллинг таблицы плавным, секрет состоит в том, чтобы НЕ использовать подпредставления, а вместо этого делать все рисование в одном пользовательском интерфейсе. По сути, кажется, что использование большого количества подпредставлений замедляет рендеринг, потому что у них много накладных расходов, и они постоянно перекомпоновываются в родительские представления.
Честно говоря, это было написано, когда 3GS был довольно новеньким, и с тех пор iDevices стали намного быстрее. Тем не менее , этот метод будет регулярно предлагается на межсетях и в других местах для высоких столов производительности. Фактически, это предложенный метод в Таблице примера кода Apple , предложенный в нескольких видеороликах WWDC ( Практическое рисование для разработчиков iOS ) и во многих книгах по программированию для iOS .
Есть даже потрясающие инструменты для разработки графики и генерации кода Core Graphics для них.
Итак, сначала я считаю, что есть причина, по которой существует Core Graphics. Это БЫСТРО!
Но как только я думаю, что у меня появляется идея: «По возможности выбирайте базовую графику», я начинаю понимать, что drawRect часто отвечает за плохую отзывчивость в приложении, чрезвычайно дорогую память и действительно нагружает процессор. По сути, я должен « избегать переопределения drawRect » ( Производительность iOS-приложения WWDC 2012 : графика и анимация )
Так что, как и все, это сложно. Может быть, вы можете помочь себе и другим понять, когда и зачем использовать drawRect?
Я вижу пару очевидных ситуаций для использования Core Graphics:
- У вас есть динамические данные (пример графика акций Apple)
- У вас есть гибкий элемент пользовательского интерфейса, который не может быть выполнен с простым изменяемым размером изображения
- Вы создаете динамическую графику, которая после визуализации используется в нескольких местах.
Я вижу ситуации, чтобы избежать Core Graphics:
- Свойства вашего вида должны быть анимированы отдельно
- У вас сравнительно небольшая иерархия представлений, поэтому любые дополнительные усилия по использованию компьютерной графики не стоят
- Вы хотите обновить части представления, не перерисовывая все это
- Макет ваших подпредставлений должен обновляться при изменении размера родительского представления.
Так дарите свои знания. В каких ситуациях вы используете DrawRect / Core Graphics (это также может быть достигнуто с помощью подпредставлений)? Какие факторы приводят вас к этому решению? Как / почему рисование в одном пользовательском представлении рекомендуется для плавной прокрутки ячеек таблицы, но Apple рекомендует использовать drawRect для повышения производительности в целом? А как насчет простых фоновых изображений (когда вы создаете их с помощью CG против изображений с изменяемым размером PNG)?
Глубокое понимание этого предмета может и не понадобиться для создания достойных приложений, но я не люблю выбирать методы, не имея возможности объяснить почему. Мой мозг злится на меня.
Обновление вопроса
Спасибо всем за информацию. Некоторые уточняющие вопросы здесь:
- Если вы рисуете что-то с помощью основной графики, но можете добиться того же с помощью UIImageViews и предварительно отрендеренного png, следует ли вам всегда идти по этому пути?
- Подобный вопрос: особенно с такими крутыми инструментами , когда вы должны рассмотреть возможность рисования элементов интерфейса в основной графике? (Возможно, когда отображение вашего элемента является переменным. Например, кнопка с 20 различными цветовыми вариациями. Есть ли другие случаи?)
- Учитывая мое понимание в моем ответе ниже, можно ли получить тот же прирост производительности для ячейки таблицы, эффективно захватив растровое изображение снимка вашей ячейки после самого сложного рендеринга UIView, и отображая его при прокрутке и скрытии сложного представления? Очевидно, что некоторые части должны быть разработаны. Просто интересная мысль у меня была.
источник
Я постараюсь сохранить резюме того, что я экстраполирую из ответов других здесь, и задать уточняющие вопросы в обновлении исходного вопроса. Но я призываю других продолжать получать ответы и голосовать за тех, кто предоставил хорошую информацию.
Основной подход
Совершенно очевидно, что общий подход, как отметил Бен Сандофски в своем ответе , должен звучать так: «Всякий раз, когда вы можете, используйте UIKit. Делайте простейшую реализацию, которая работает. Профиль. Когда есть стимул, оптимизируйте».
Почему
Рисование содержимого ячеек в одном плоском UIView может значительно улучшить ваш FPS на прокручиваемых таблицах.
Как я уже говорил выше, CPU и GPU - два возможных узких места. Поскольку они обычно работают с разными вещами, вы должны обратить внимание на то, с каким узким местом вы сталкиваетесь. В случае с прокруткой таблиц, Core Graphics не рисует быстрее, и поэтому может значительно улучшить ваш FPS.
Фактически, Core Graphics вполне может быть медленнее, чем вложенная иерархия UIView для начального рендеринга. Тем не менее, похоже, что типичная причина прерывистой прокрутки в том, что у вас узкое место в GPU, поэтому вам нужно устранить это.
Почему переопределение drawRect (с использованием основной графики) может помочь при прокрутке таблицы:
Из того, что я понимаю, графический процессор не отвечает за начальный рендеринг представлений, а вместо этого передает текстуры или растровые изображения, иногда с некоторыми свойствами слоя, после их рендеринга. Затем он отвечает за наложение растровых изображений, рендеринг всех этих эффектов слоя и большую часть анимации (Core Animation).
В случае ячеек табличного представления графический процессор может быть узким местом со сложными иерархиями представлений, потому что вместо анимации одного растрового изображения он анимирует родительское представление и выполняет вычисления макета подпредставления, эффекты рендеринга слоя и компоновки всех подпредставлений. Таким образом, вместо анимации одного растрового изображения, оно отвечает за взаимосвязь множества растровых изображений и то, как они взаимодействуют, для одной и той же области пикселей.
Итак, в итоге, причина, по которой ваша ячейка в одном виде с графическим ядром может ускорить прокрутку таблицы, не в том, что она рисует быстрее, а в том, что она снижает нагрузку на графический процессор, что является узким местом, создающим проблемы в этом конкретном сценарии. ,
источник
Я разработчик игр, и я задавал те же вопросы, когда мой друг сказал мне, что моя иерархия представлений на основе UIImageView замедлит мою игру и сделает ее ужасной. Затем я приступил к исследованию всего, что я мог найти о том, использовать ли UIViews, CoreGraphics, OpenGL или что-то стороннее, например, Cocos2D. Последовательный ответ, который я получил от друзей, учителей и инженеров Apple из WWDC, заключался в том, что в конце не будет большой разницы, потому что на каком-то уровне они все делают одно и то же . Опции более высокого уровня, такие как UIViews, полагаются на опции более низкого уровня, такие как CoreGraphics и OpenGL, просто они заключены в код, чтобы вам было легче его использовать.
Не используйте CoreGraphics, если вы просто собираетесь переписать UIView. Тем не менее, вы можете получить некоторую скорость с помощью CoreGraphics, до тех пор , как вы делаете весь рисунок в одной точке зрения, но это действительно стоит это? Ответ, который я нашел, обычно нет. Когда я впервые начал свою игру, я работал с iPhone 3G. По мере того, как моя игра усложнялась, я начал видеть некоторое отставание, но с новыми устройствами это было совершенно незаметно. Сейчас у меня много действий, и единственное отставание - падение на 1-3 кадра в секунду при игре на самом сложном уровне на iPhone 4.
Тем не менее я решил использовать инструменты, чтобы найти функции, которые занимали больше всего времени. Я обнаружил, что проблемы не были связаны с моим использованием UIViews . Вместо этого он неоднократно вызывал CGRectMake для определенных вычислений обнаружения столкновений и загружал изображения и аудиофайлы отдельно для определенных классов, которые используют одни и те же изображения, вместо того, чтобы получать их из одного класса центрального хранилища.
Таким образом, в итоге вы можете добиться небольшого выигрыша от использования CoreGraphics, но обычно это того не стоит или может вообще не иметь никакого эффекта. Единственный раз, когда я использую CoreGraphics, это когда я рисую геометрические фигуры, а не текст и изображения.
источник