Intereting Posts
обновление UIView синхронно с изменением значений массива iOS – обработка нескольких флажков Можем ли мы использовать как coredata, так и SQlite в приложении iOS ios 8.1 симулятор – запросы на кросс-начало поддерживаются только для HTTP Повторите этот код для соответствия ARC Поворачивайте экран вручную до Пейзажа, и слева от экрана находится белая полоса, на которой была помещена старая строка состояния Как сохранить локальную переменную, заданную в блоке? Как установить приоритет в UIScrollview и анимации Objective-C: UIImageWriteToSavedPhotosAlbum () + асинхронный = проблемы Ошибка идентификатора приложения Facebook UILocalNotification – Огонь в 6:00 утра в каждом часовом поясе SpriteKit touchhesMoved является неустойчивым при использовании в подклассе SKSpritenode Анимация Push Segue без UINavigationController Почему Sprite Kit SKNode подвергает zRotation, xScale и yScale вместо простого преобразования? Перетаскивание объектов из одного CCLayer в другой

Для производительности лучше ли скрывать или удалять CALayers на iOS?

Это связано с следующим вопросом: как повысить производительность анимации CALayer?

В настоящее время у меня есть представление, которое может иметь несколько сотен CALayers. Я знаю, что многие CALayers вызовут снижение производительности, ограниченное процессором, но я хотел посмотреть, экспериментировал ли кто-то там с несколькими из следующих методов и может дать указания.

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

Перенастройка одного слоя vs Несколько предварительно нарисованных слоев

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

[layer configureWithZoom:zoom]; [layer setNeedsDisplay]; 

против

 layer1.hidden = (zoom == DEFAULT_ZOOM); layer2.hidden = (zoom != DEFAULT_ZOOM); 

Я понимаю, что наличие пучка слоев увеличит мой объем памяти, и если бы у меня было 50 слоев раньше, у меня теперь есть 100 уровней. Но с точки зрения производительности это поможет?

Скрытие против удаления

Учитывая вышеизложенное, теперь у меня есть слои, которые не нужны во все времена. Лучше ли скрывать эти слои или удалять их?

Установка layer.hidden = YES vs [layer removeFromSuperlayer] когда я хочу, чтобы он ушел.

Установка layer.hidden = NO vs [superlayer addSublayer:layer] когда я хочу, чтобы он вернулся.

Если я скрою слой, но одушевляю суперслоя, есть ли производительность во время анимации, потому что подслой скрыт, а не удален? Как эта производительность влияет на добавление / удаление подслоев?

Родительский слой против прямого расслоения

Одна из проблем с отдельными слоями теперь в том, что мне нужен код для управления ими как единицей. Раньше изменение положения слоя было простым, как layer.position = newCoordinates; , Теперь мне нужно будет:

 layer1.position = newCoordinates1; layer2.position = newCoordinates2; 

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

Однако теперь это вводит 3-й уровень (в начале у нас было 1, теперь у нас 3). Мне любопытно, если слой, который не имеет фактического чертежа, кроме его подслоев, имеет какое-то влияние на производительность. В основном, пустой слой, имеющий 2 подслоя, имеет производительность, по сравнению с тем, что эти два подслоя добавлены непосредственно к суперслою.

Любые рекомендации будут оценены.

Перенастройка одного слоя vs Несколько предварительно нарисованных слоев

Это зависит от того, как вы рисуете здесь. Я предполагаю, что вы используете drawInContext CALayer с каким-то специальным кодом? Если да, это определенно поможет, если вызов этого кода чертежа не требуется при каждом изменении уровня масштабирования. Объем памяти из двух слоев, как и прежде, действительно не должен навредить вам.

Скрытие против удаления

Я работаю с подобной настройкой для вас уже довольно долгое время и одновременно имею сотни (тысячи) CALayers на экране. Из моих экспериментов я узнал, что из скрытых слоев наблюдается огромный успех. Для меня всегда лучше было полностью удалить и повторно добавить их позже.

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

Родительский слой против прямого расслоения

О третьем вопросе: я не уверен на 100 процентов, если ваш пустой слой, который работает как родительский для ваших двух слоев, – это удар производительности, но я бы предположил, что это (из моего опыта каждый дополнительный уровень, который CA должен обрабатывать он работает медленнее). Вопрос в следующем: можете ли вы сделать это без слоя между ними? Есть ли определенный порядок, в котором должны находиться ваши слои?

Вы можете написать собственный класс, подклассифицирующий NSObject, который берет ваши два слоя и управляет им всем (изменение позиции, удаление и добавление из суперслоя и т. Д.). Таким образом, у вас будет простой интерфейс, но нет дополнительного слоя на экране.

Если это не вариант, вы можете попытаться использовать CATransformLayer в качестве слоя компоновки для двух слоев. Этот слой не делает ничего, кроме как слой для компоновки (и его можно использовать для 3D). Возможно, в вашем сценарии это занимает меньше производительности, чем «нормальный» CALayer.

Общая эффективность

Если возможно, не используйте drawInContext для рисования ваших слоев. Если вы можете, используйте CAShapeLayer для своих звезд, он намного быстрее и имеет приятное сглаживание.

Посмотрите на CPU-метр, встроенный в Xcode (а не на профайлер). Там вы видите CPU-использование «других процессов». В CA-приложениях, которым требуется большая производительность, этот раздел «других процессов» в основном представляет собой CA-RenderServer (backboardd). Здесь вы можете увидеть, сколько CPU стоит вам сейчас.

В противном случае, если вас беспокоит использование вашей памяти, проверьте профилировщик распределения (на этот раз настоящий профилировщик) и проверьте, сколько памяти используют разные версии вашего кода (50 против 100 уровней).