АРК: Память не восстанавливается? - PullRequest
3 голосов
/ 22 февраля 2012

Я работаю над приложением для iPad (только) и наткнулся на странную проблему. Приложение перестает работать после предупреждения о памяти на iPad 1, но отлично работает на iPad 2. Я использую ARC и нацеливаюсь на iOS 5. Я использую перья, и большинство моих активов отображаются с помощью UIImageViews. У меня также есть несколько сотен кнопок и множество распознавателей жестов ... Я повторно посмотрел видео WWDC11 (сеансы 323 и 322) на ARC, и я, кажется, не делаю ничего особенного.

Приложение интенсивно использует UIImage, я делаю много анимаций, используя UIImage. Однако я использую конструктор initWithContentsOfFile, а не вызов imageNamed. Я пытаюсь предотвратить кэширование изображений системой.

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

Приложение использует UINavigationController, который никогда не имеет более 1 UIViewController в своем стеке. Я могу подтвердить, что это правда, потому что didReceiveMemoryWarning вызывается только на текущем контроллере представления (я регистрирую вызов).

Я не понимаю, почему Instruments сообщает о больших числах (как будто контроллеры представления не освобождаются) в инструментах Allocations и VM Tracker. Инструмент Allocations показывает небольшое падение, когда я перемещаюсь от одного контроллера представления к другому (что я и ожидаю), но инструмент VM Tracker показывает, что Dirty Size не сбрасывается, когда я делаю то же самое. В конце концов приложение использует слишком много памяти и завершает работу (на iPad 1). Когда я получаю предупреждения о памяти на iPad 2, приложение НЕ закрывается, хотя ...

Такое ощущение, что мои изображения, звуки или изображения не разрушаются, а память не восстанавливается ... Моя иерархия объектов очень проста, и не должно быть никаких циклов сохранения. У меня даже нет простых делегатов ...

У вас есть предложения? Я действительно не хочу выпускать это приложение только для iPad 2 или новее ... Это приложение для детей, и это будет жалко ... Я был бы намного счастлив узнать, что я делаю что-то не так , так как я действительно хочу убедиться, что это приложение лучшее, что может быть ...

Ура, Ник

Ответы [ 2 ]

1 голос
/ 26 февраля 2012

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

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

Как только я буду доволен этим и почувствую, что он готов к обмену, я опубликую класс (ы) на GitHub.

1 голос
/ 22 февраля 2012

Есть способы сказать, «оптимизировать» ваши объекты, установив их свойства на nil, когда определенные вещи не нужны - поэтому, когда вы больше не можете писать метод dealloc, вы можете сделать self.object = nil (когда это уместно), что в конечном итоге делает что-то подобное в мире, не являющемся ARC, для свойства 'retain' (т. е. strong):

- (void)setObject:(id)newObject
{
   [object release]; // send release message to current object
   object = newObject; // set reference to newObject
   [object retain]; // send retain message to newObject
}

Теперь, когда в ARC вы не /не может написать retain / release самостоятельно в вашем коде, компилятор вставляет эти вызовы для вас, что означает, что на практике установка свойства nil сделает это в приведенном выше примере:

[object release]; // send release message to current object
object = nil; // set reference to nil
[object retain]; // send retain message to nil (no effect)

Более тогоэто только вершина айсберга - вы должны убедиться, что в вашем коде нет циклов сохранения , что может привести к утечке объектов без обращения к их уничтожению.Это означает, что могут быть места, где вы используете strong ссылки на свойство (т. Е. Объект), когда вы должны использовать свойство weak.Разница в том, что сильные ссылки retain ed, а weak ссылки assign ed, первая имеет увеличенный retainCount, а вторая приводит к присваиванию свойства, которое выглядит следующим образом, если оно написано от руки:

- (void)setObject:(id)newObject
{
   object = newObject;
}
...