IOS 6.x Как использовать Sprite Sheet с initWithContentsOfFile, imageNamed

Я искал эти темы и другие сайты, но не нашел способ сделать это эффективно и дружественно к памяти. Итак, вот моя история:

В моем приложении IOS (iPad) используются листы спрайтов (большое изображение, такое как 2k x 2k при 16 бит / с, которое состоит из множества меньших спрайтов). Я создал класс атласа спрайтов, который управляет этими листами, обрабатывает анимацию спрайтов и другие функции.

Идея (в методе загрузки) состоит в том, чтобы загрузить лист из файловой системы, разделить его на UIImages (по одному на спрайт) с помощью CGImageCreateWithImageInRect, а затем утилизировать загруженный лист. Кажется достаточно простым.

Обратите внимание, что лист загружается в UIImage с помощью initWithContentsOfFile или imageNamed (подробнее об этом ниже).

Желание сохранить файловую память, используя листы спрайтов, а затем сохранить память времени выполнения, сохранив только фактические спрайты как UIImages. В моих экспериментах до сих пор это то, что я нахожу происходящим:

Если я использую initWithContentsOfFile, я вижу (из Instruments), что он, кажется, делает файл open, fstat64 и close для файла для каждого спрайта в нем. Это занимает ужасное количество времени, чтобы загрузить все спрайты. На самом деле кажется, что загружается весь лист, захватывается один спрайт, закрывается лист, а затем снова загружается весь лист для следующего спрайта, пока все они не будут созданы. Кроме того, он, похоже, потребляет много памяти (что подтверждается "предупреждением о получении памяти" после загрузки только второго листа, а также распределением инструментов).

Затем я попытался imageNamed (который кэширует лист). Загрузка файла происходит один раз, и это происходит НАМНОГО быстрее. Все кажется хорошим и на самом деле, и я могу идти, пока много листов не загружены. Но в конце концов появляется страшное "предупреждение о получении памяти"... и через несколько секунд приложение вылетает. Похоже, что тот случай, когда кэшированное изображение (даже если указатель установлен на нуль после удаления спрайтов) никогда не исчезает. Я прочитал несколько постов, в которых также говорится, что это, похоже, его поведение (хотя другие посты говорят о других вещах, так что это не является окончательным - кто-нибудь знает окончательно?).

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

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

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

[и да, я знаю, что IOS 7 имеет SpriteKit. Но это также должно работать на IOS 6.x.]

Интересным моментом является то, что на оригинальном iPad версия imageNamed работает нормально, без "предупреждения о получении памяти". Это мог быть IOS 5.x. Но приложение упадет на устройстве iPad 2.

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

И пока я занимаюсь этим, кто-то может прояснить этот момент:

True или False: при использовании CGImageCreateWithImageInRect фактически создается из новой памяти растровое изображение размером указанного прямоугольника, а затем копируется из исходного UII изображения пикселей в эту новую память (в отличие от настройки растрового формата и наличия указатель указывает на исходные данные пикселей UIImage). Я думаю, что это правда, но хочу проверки.

Спасибо!

0 ответов

Другие вопросы по тегам