создание пула автозапуска и его слив в другом контексте

В контроллере представления у меня есть UIImageView в качестве подпредставления. На willRotateToInterfaceOrientation я заменяю его другим UIImageView. Если оба они находятся в памяти одновременно, иногда происходит сбой при удалении из-за очень большого размера изображений. Поэтому я хочу убедиться, что полностью освободил первый, прежде чем делать новый. Когда я вызываю на нем removeFromSuperview, я думаю, что в какой-то момент позже он в основном автоматически освобождается, но мне нужно, чтобы его немедленно освободили.

Похоже, мне нужен собственный пул автозапуска при создании UIImageView, а затем его сливают, когда вызывается willRotateToInterfaceOrientation, после вызова removeFromSuperview. Но в документации сказано:

Пул с автоматическим выпуском всегда должен сливаться в том же контексте (например, при вызове метода или функции или в теле цикла), в котором он был создан. Пулы с автоматическим выпуском используются «встраиваемыми». Обычно не должно быть причин, по которым вы должны сделать пул автозапуска переменной экземпляра объекта.

Итак, каков «правильный» способ сделать это?


person jonydep    schedule 23.02.2012    source источник


Ответы (2)


Лучшее, что можно сделать, - это оптимизировать ваши изображения. Крайне важно, чтобы пул автозапуска выделялся и осушался в одном контексте. Первое, что вам следует сделать, это уменьшить размер изображения. Если это png, попробуйте pngcrush. Если изображения все еще слишком большие, рассмотрите возможность использования mmap для загрузки частей изображения за раз.

Настройка производительности

Установите ограничения на размер ресурсов.
Не загружайте большой файл ресурсов, если подойдет и меньший. Вместо изображения с высоким разрешением используйте изображение, размер которого соответствует устройствам на базе iOS. Если вам необходимо использовать большие файлы ресурсов, найдите способы загрузить только ту часть файла, которая вам нужна в любой момент времени. Например, вместо того, чтобы загружать весь файл в память, используйте функции mmap и munmap для отображения частей файла в память и из нее. Дополнительные сведения о сопоставлении файлов с памятью см. В разделе Рекомендации по производительности файловой системы.

person Joe    schedule 23.02.2012
comment
будет ли уменьшение размера диска изображения со сжатием иметь значение для объема оперативной памяти после его загрузки как UIImage? Я предполагал, что он всегда будет храниться в ОЗУ в несжатом виде? - person jonydep; 23.02.2012
comment
Это как минимум поможет снизить пик памяти, поскольку он загружает образ с диска, чтобы поместить его в ОЗУ. - person Joe; 23.02.2012
comment
ах хорошо спасибо. но фактический размер файла бледнеет по сравнению с несжатыми изображениями ... и я мог бы уменьшить пик наполовину, если бы я мог освободить старое изображение перед созданием нового, неужели нет способа сделать это? mmap, кстати, выглядит интересно, я не знал об этом .. - person jonydep; 23.02.2012
comment
Я полагаю, вы могли бы попробовать отложить загрузку следующего изображения до следующего цикла выполнения, который должен дать пулу автозапуска время для очистки. Попробуйте использовать (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay и передать 0 для задержки. - person Joe; 23.02.2012
comment
Ваше последнее предложение - это то, чем я закончил, спасибо за это. кажется, это единственное, что на самом деле гарантирует, что старый материал будет удален из памяти до того, как будет создан новый. это означает, что между ними есть короткий период черного экрана, но я думаю, что это неизбежно. - person jonydep; 24.02.2012

Подумайте о пулах с автоматическим выпуском как о локальных стеках потоков. Вы не упорствуете в контекстах или других пулах автозапуска - нарушая порядок. Использование пула с автозапуском в качестве ивара часто является ошибкой. Использование пула автозапуска из нескольких потоков также является ошибкой.

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

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

person justin    schedule 23.02.2012