Удаление CAKeyframeAnimation не освобождает память

Я добавляю CAKeyframeAnimation в слой ImageView для представления анимации изображения:

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
animation.values = arrayOfImages;
[animation setRemovedOnCompletion:YES];
animation.delegate = self;
[animation setValue:delegate forKey:@"AnimatedImageViewDelegate"];
animation.repeatCount = repeatCount;
animation.fillMode = kCAFillModeForwards;
animation.calculationMode = kCAAnimationDiscrete;
[animation setValue:animationName forKey:@"name"];

Когда я хочу запустить анимацию, я вызываю:

animation.duration = duration;
[self.layer addAnimation:animation forKey:animationName];
[self.layer setContents:[animation.values lastObject]];

Когда анимация закончится, я хочу полностью удалить ее и освободить память.

[self.layer removeAllAnimations];       
[self.layer removeAnimationForKey:animationName];

Выполняя это и используя Instruments-Activity Monitor, память не освобождается, пока я не выпущу полный imageView.

Как я могу освободить эту анимационную память, не уничтожая UIImageView???


person nano    schedule 26.01.2012    source источник
comment
вы можете попробовать взять его в autoreleasepool   -  person Volodymyr B.    schedule 14.02.2012


Ответы (4)


Вы используете удобный метод для создания экземпляра объекта. Таким образом, вы не сможете контролировать, когда объект будет фактически выпущен. Чтобы контролировать это, вам нужно будет выделить объект и освободить его самостоятельно:

Создайте экземпляр:

CAKeyframeAnimation *animation = [[CAKeyframeAnimation alloc] init];

Затем после завершения анимации вызовите после удаления строк:

[animation release];
person Jeshua Lacock    schedule 26.01.2012
comment
[CAKeyframeAnimation animationWithKeyPath:] возвращает автоматически выпущенный объект (в соответствии с соглашением об именах), и он, похоже, не сохраняет его (по крайней мере, он не делает этого в представленном им коде), поэтому с ним все должно быть в порядке. Выполнение alloc/release вместо этого не изменит этого. Действительно, из его кода я бы сказал, что все в порядке, поэтому проблема должна быть в другом месте. - person DarkDust; 27.01.2012
comment
Верно, за исключением того, что он не имеет контроля, когда он выпущен, когда он автоматически выпущен. Похоже, что он автоматически освобождается, когда представление уничтожается, поэтому кажется, что по крайней мере что-то стоит попробовать. - person Jeshua Lacock; 27.01.2012
comment
Даже при выделении/инициализации и освобождении анимации память не уменьшается, когда я использую Activity Monitor. Таким образом, нет никакой разницы с точки зрения памяти с использованием автовыпуска или выпуска. Если я прокомментирую строку animation.values ​​= arrayOfImages; анимация не отображается, и память не увеличивается, поэтому моя проблема в том, что когда анимация заканчивается, память вообще не освобождается, если я не освобождаю ImageView. - person nano; 27.01.2012

Во-первых, если это проект iOS 5, ARC должен обрабатывать ваши релизы за вас, что действительно приятно!

Теперь -- я использовал много анимаций в своем проекте и заметил подобные всплески в куче. Я предполагаю, что CA кэширует многое из того, что анимировано внутри. Чтобы убедиться, что эти элементы действительно выпускаются автоматически, я рекомендую настроить тест на распределение или утечку с помощью инструмента tools и сделать следующее:

  1. Определите ситуацию, в которой вы будете запускать анимацию.
  2. Отметьте кучу после завершения анимации.
  3. Запустите что-то, что приведет вас к другому представлению, где объекты должны были быть удалены.
  4. Повторите шаги 1-2-3 столько раз, сколько хотите. Я обычно делаю это около 10 раз или около того.

Вот и все .. в основном анимация - отметка - отмена - анимация - отметка. Вы должны увидеть, что heapshots уменьшаются до 0 или почти до 0, если CoreAnimation корректно автоматически освобождает объекты!

Для получения дополнительной информации о том, как проводить подобное тестирование, ознакомьтесь с этой статьей:

http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-нежелательная-память-growth/

person Jim Jeffers    schedule 14.02.2012
comment
Спасибо за Ваш ответ. Он уменьшается почти до 0 после завершения анимации, но только если я отпущу ImageView. Без его освобождения куча увеличивается довольно сильно (от 40 КБ до 800 КБ каждый раз). Это означает, что CoreAnimation не освобождается после завершения. - person nano; 15.02.2012

У меня такая же проблема с памятью с CAKeyframeAnimation, когда заданные значения = массив изображений. И я вижу, что проблема, которую я получаю, заключается в том, что изображения инициируются [UIImage imagewithname:], который по умолчанию кэшируется в памяти. Итак, мое решение - изменить использование [UIImage imageWithContentsOfFile:] Надеюсь, это будет полезно.

person Đông Hà    schedule 23.04.2015

В моем случае CAKeyframeAnimation, добавленный в представление imageView и контейнера, не освобождается, даже если его нет в иерархии представлений.

Оказалось, что его держал делегат CAKeyframeAnimation. Я просто удалил делегата:

beatAnimation.delegate = nil
person hasan    schedule 15.04.2018