UIImage выпущен, но CGImage не выпущен

Кажется, у меня проблема с управлением памятью, когда я создаю экземпляры UIImage, которые CGImages не выпускаются.

У меня есть пейджинг UIScrollView для прокрутки серии изображений в формате JPG. Ниже приведен весь мой класс, который представляет собой просмотр страницы в представлении прокрутки пейджинга.

Код запускается в основном потоке. В коде используется ARC. Я попытался загрузить изображения с помощью imageWithContentsOfFile: (возвращает объект с автореализацией), а также initWithContentsOfFile: (возвращает сохраненный объект). Я попробовал @autoreleasepool и использовал performSelectorOnMainThread, чтобы гарантировать, что код запускается в основном потоке, как это предлагается в других сообщениях.

При прокрутке изображения использование памяти увеличивается только до тех пор, пока приложение не будет завершено, как показано на скриншоте из инструментов. Обратите внимание на высокое выделение изображения io.

Скриншот, показывающий использование виртуальной памяти

Виртуальная память Tracker

На следующем скриншоте видно, что GTGImageScrollerPageViews, UIImageViews и UIImages освобождаются. Обратите внимание, что существуют объекты Transitory для этой нумерации в высоких 300-х годах. Однако CGImages не освобождаются, а количество живущих CGImages находится в высоких 400 и 0 Transitory.

Снимок экрана с указанием распределений

ассигнования

EDIT: Раньше я занимался переработкой и повторным использованием экземпляров GTGImageScrollerPageView в ScrollView, так как это общий шаблон для scrollviews, подобного этому. Чтобы упростить при попытке отладки этой проблемы, я разрешаю освободить весь GTGImageScrollerPageView после его отображения в ScrollView. Как вы можете видеть во втором изображении выше, есть только 4 жителя GTGImageScrollerPageView и 377 преходящих, есть также 388 UIImageViews и 389 UIIMages, перечисленных как преходящие, поэтому кажется, что UIImageViews и UIImages освобождаются от штрафа.

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

Снимок экрана, показывающий использование виртуальной памяти с использованием CGImageRelease

Использование виртуальной памяти

Снимок экрана, показывающий распределения с использованием CGImageRelease

введите описание изображения здесь

В профилирующих выводах, где используется CGImageRelease, вы можете видеть, что правильное количество объектов CGImage – это Living and Transitory, и эта память не растет неограниченно. Кроме того, приложение не сбой во время использования с использованием CGImageRelease.

Если это было какое-то системное кэширование CGImage, тогда он должен освобождать память при поднятии предупреждения о памяти, но это не так. Память продолжает расти.

Что здесь может вызвать этот неограниченный рост памяти?

Вот код для просмотра страницы

EDIT: В ответ на комментарии я обновил код, чтобы упростить его, тем самым устраняя отвлекающие факторы, такие как ivars и свойства, которые не нужны для демонстрации проблемы. Проблема остается неизменной, и при профилировании результаты одинаковы. Я также добавил в NSLog, который также выводит поток. Я вижу, что dealloc вызывается как ожидалось в GTGImageScrollerPageView, и он всегда является нитью # 1, и вызов displayAspectThumbImage всегда находится в потоке # 1.

Я действительно не верю, что что-то не так с кодом, который представлен здесь, и это подтверждается щедрым усилием Роба. Что-то еще вызывает это, но весь код, связанный с загрузкой и отображением изображения, находится здесь; здесь нет другого кода. Единственное замечательное, что я мог подумать о повышении, это то, что метод displayAspectThumbImage вызывается из scrollViewDidScroll и scrollViewDidEndDecellerating методов делегата scrollview, но тот факт, что методы вызываются в основном потоке, должен исключать проблемы автозавершения из-за запуска в другом потоке ,

Я проверил и NSZombies не включен, и нет никаких Зомби, увеличивающих использование моей памяти. Действительно, когда метод CGImageRelease называется, использование памяти довольно плоское, как видно на скриншоте выше.

@implementation GTGImageScrollerPageView - (void)dealloc { NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSThread currentThread]); } - (void)displayAspectThumbImage:(NSString *)path { NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSThread currentThread]); UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.bounds]; [self addSubview:imageView]; UIImage *image = [[UIImage alloc] initWithContentsOfFile:path]; [imageView setImage:image]; //If uncommented CGImages are disposed correctly //CGImageRelease([imageView.image CGImage]); } @end 

Протестировано:

iOS 6.1.4

iOS 5.0.1

3 Solutions collect form web for “UIImage выпущен, но CGImage не выпущен”

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

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

Это особенно странно, потому что библиотека не использовалась где-то рядом с кодом, который протекал. Он использовался только в одном месте во всем проекте, но в любой момент, когда я использовал UIImage, кажется, что это повлияло на экземпляр UIImage. Простого присутствия этой категории в проекте было достаточно. Это стало настоящим сюрпризом.

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

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

Я сделал простой бесконечный скроллер, используя ваш код, и после прокрутки почти 100 изображений использование памяти было, как и следовало ожидать, совершенно беспрецедентным:

ассигнования

В.М.

Глядя на ваш источник, я бы рекомендовал несколько мелочей (например, я бы поставил aspectImageView в расширение частного класса, а не на .h, я предполагаю, что вы устанавливаете pageIndex из вызывающей процедуры, но я бы добавил его как параметр displayAspectThumbImage , я бы сделал aspectImageView weak свойством и соответствующим образом aspectImageView код (например, создайте представление изображения, добавьте его как subview, затем установите свойство weak изображения для указания на этот объект) и т. д.), но ни один из них не имеет прямое отношение к вашей проблеме здесь.

Итог, ваша проблема не остается в коде, который вы нам поделили.

Попробуйте использовать свойство вместо ivar.

@property (неатомный, сильный) UIImageView * aspectImageView;

  • Почему cgImage ?.cropping вращает изображение?
  • iphone 4s - Размеры изображения CGImage UIImage
  • Получение CGImage от CIImage
  • Crash, в то время как iOS принимает снимок приложения
  • Могу ли я редактировать альфа-маску UIImage в UIImageView без необходимости переместить слишком много памяти?
  • Предупреждение CGContextClear
  • Радости в реальном времени gif-декодирования
  • Качество сжатия JPEG с использованием CGImage
  • Пользовательский фон анимации
  • Рисование изображения в Swift длится вечно
  • Должен ли я использовать UIImage или CGImage в Swift iOS App?
  • Interesting Posts

    Быстрые варианты: проблема языка или что-то не так?

    Как получить URL-адрес для PHAsset?

    Как я могу сделать какие-либо ссылки в веб-обзоре на сафари в Xcode?

    Прокрутите UITableViewCell до видимого, не работая по назначению

    Анимация кадра UIView, subview UIScrollView не всегда оживляет

    Ошибка Paypal iOS SDK Sandbox при оплате

    Обзор приложения – укажите на dev api вместо prod

    Синхронизация данных iOS и Mac OS X

    Удаление покупки в учетной записи пользователя «Проверка покупок»

    Это IP, сайт или мобильное приложение не имеет права использовать этот ключ API. Как исправить эту проблему для приложения ios?

    UICollectionReusableView для заголовка раздела не работает

    Объект iOS Custom MKAnnotation, напоминающий анимацию MKUserLocation

    Измените звуковой файл push-уведомления, он работает только после перезагрузки iOS

    Как добавить дополнительную информацию в раздел NSFetchedResultsController

    Выход монофонического воспроизведения с Core Audio

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.