Я использую инструменты, чтобы увидеть утечки памяти. По крайней мере, в одном сценарии, когда я постоянно пролистываю слайды / страницы (внутри UIScrollView), я не вижу утечки памяти. Используя инструменты - в разделе «Срок службы распределения» Я переключаюсь на просмотр «Создано и все еще жив» и вижу, что объем памяти составляет около 1,17 МБ. Я предполагаю, что это означает, что мое приложение использует только этот объем фактической памяти, а остаток правильно перерабатывается.
Однако после пролистывания 100 или около того страниц, я получаю предупреждение о памяти, а затем несколько моих представлений выгружаются, что приводит к сбою всего приложения.
Если я не использую много памяти и не имею утечки памяти, почему я получил память предупреждение? Поскольку я ничего не могу выпустить, я не вижу способа избежать сбоя. Кто-нибудь сталкивался с этой ситуацией или знает, что я могу сделать? Я неправильно интерпретирую что-нибудь из Instruments? Большое спасибо за любой комментарий.
Если соответствующий объект изображения еще не находится в кеше, этот метод загружает данные изображения из указанного файла, кэширует их , а затем возвращает получившийся объект.
Таким образом, каждое изображение, которое вы загружаете с помощью imageNamed:
, будет продолжать существовать в кэше после того, как вы освободите свое последнее право собственности на него.
Инструменты не показывают это как утечку, потому что, строго говоря, это не так: кое-что (UIImage) все еще знает об этих изображениях. Инструмент Leaks покажет только утечку для объекта, который существует, но ничего не знает о нем.
Однако вы все еще можете увидеть это в инструментах.
Затем, если навести указатель мыши на столбец адреса для строки экземпляра, вы увидите ту же кнопку; на этот раз щелкнув по нему, вы перейдете к истории этого адреса, включая все создание, сохранение, выпуск и освобождение объектов с этим адресом.
Здесь вы можете увидеть распределение изображения (в классе UIImage, упорядоченное вами на несколько кадров вниз), удержание (вами) и освобождение (вами). Вы также можете видеть, что он не был выпущен UIImage - кэш + [UIImage imageNamed:]
по-прежнему владеет изображением, отсюда и «утечка».
Если вы не хотите, чтобы изображения накапливались подобным образом, загрузите их самостоятельно, используя imageWithContentsOfFile:
и метод - [NSBundle pathForResource: ofType:]
].
ОБНОВЛЕНИЕ: Я читал, что начиная с iOS 3, UIImage будет очищать свой кеш (по крайней мере, в некоторых) ситуациях с нехваткой памяти, так что это не должно быть такой большой «утечкой», как раньше. Вы, вероятно, по-прежнему будете видеть скопление памяти, но в конечном итоге вы увидите, что куча рушится.Если вы все еще видите скопление памяти и можете доказать, что это вина Apple, вам следует задокументировать свои доказательства и зарегистрировать ошибку .
Установлено ли для переменной среды NSZombieEnabled
значение yes? Это приведет к тому, что освобожденные объекты останутся в памяти, что не позволит вам восстановить память. Так что попробуйте отключить его, если он активен.
Обнаружен источник проблемы. Это в следующем фрагменте
UIImage *image = [UIImage imageNamed:imageFile];
cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)];
cartoon.image = image ;
cartoon.backgroundColor = [UIColor brownColor];
. У меня есть сотни изображений плюс некоторый текст на каждой странице, и пользователь может пролистывать их, щелкая пальцем (точно так же, как в приложении для фотографий iphone). Я создаю только 3 страницы в своем UIScrollView и загружаю / выгружаю (а также освобождаю) все, что я явно выделил. Поэтому, когда дело доходит до выпуска мультфильма, я просто выпускаю мультфильм UIImageView, а не UIImage, думая, что он будет выпущен автоматически.
Но похоже, что он не выпускается автоматически. Мое приложение получает предупреждение о памяти (я не предпринимаю никаких действий), и ОС выгружает мои представления, вызывая сбой.
Когда я закомментирую две строки (измененный фрагмент ниже), проблема исчезнет. Никаких предупреждений, никаких сбоев.
//UIImage *image = [UIImage imageNamed:imageFile];
cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)];
//cartoon.image = image ;
cartoon.backgroundColor = [UIColor brownColor];
Кто-нибудь знает, как обойти эту проблему? Есть ли способ принудительно освободить память из UIImage при появлении предупреждения?