Память не освобождается правильно? - PullRequest
0 голосов
/ 27 ноября 2010

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

Этот кеш - это в основном NSMutableDictionary с ключами, которые связаны с идентификатором изображения. Каждый объект в кэше также является NSDictionary с URL, URL-адресом изображения, заголовком и объектом NSData. Когда я загружаю изображение, я добавляю новый объект словаря в кеш с этими элементами. Я храню объект NSData следующим образом: NSData * imgData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: imageurl]]; Затем я добавляю этот объект в дочерний объект словаря.

Это, очевидно, занимает большой объем оперативной памяти после того, как большое количество фотографий сохранено и кэшировано, поэтому я отвечаю на предупреждение о памяти, очищая весь кэш. Проблема заключается в том, что независимо от того, что я пытался, не освобождается RAM. Объекты исчезают (как и должны), но не возвращают ОЗУ. Я пытался сделать следующее:

  • Цикл по словарю кэша, освобождение объекта данных в дочернем словаре, затем, когда все элементы циклически пройдены, удаляются все дочерние объекты словаря кэша.
  • Цикл по словарю кеша, освобождение дочернего словаря, удаление всех объектов по окончании
  • Даже удаляя все объекты, затем освобождая весь объект кэша (затем воссоздавая его, потому что он все еще должен использоваться)
  • И другие случайные комбинации освобождения, удаления и т. Д.

Проблема в том, что НИЧЕГО, что я пытался освободить ОЗУ. Есть ли что-то, что я делаю не так с освобождением памяти объектов NSData?

Ответы [ 2 ]

1 голос
/ 27 ноября 2010

Способ управления памятью в Objective-C работает, когда вы получаете право собственности на объект путем выделения / инициации, -сохранения или -копирования его, и вы закрываете его, когда он больше не нужен через -release или -autorelease. *

То, что вы хотите сделать, это:

1) Создать объект данных

NSData *imgData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageurl]]; 

Теперь у вас есть объект, на который указывает imgData.

2) Добавьте этот объект в свой дочерний словарь

[childDictionary setObject:imgData forKey:@"imgData"];

3) Отклонить объект данных. Тебе это больше не нужно. childDictionary нуждается в этом, но это не ваша проблема. childDictionary, как и любой другой объект, отвечает за управление собственной памятью и владением.

[imgData release];

Другой способ сделать это - создать автоматически выпущенную версию объекта данных и добавить ее в словарь.

Далее вам необходимо убедиться, что вы правильно управляете памятью childDictionary и cache. Например:

1) Создать автоматически выпущенный childDictionary

NSMutableDictionary *childDictionary = [NSMutableDictionary dictionary];

2) Добавить материал в childDictionary (как мы делали раньше)

3) Добавить childDictionary в кеш

[cache setObject:childDictionary forKey:yourKey];

4) Поскольку childDictionary был создан с автоматическим выпуском, вам не нужно (и не нужно) выпускать его сейчас, когда он вам не нужен. Это будет автоматически выпущено основным пулом автоматического выпуска позже. Если вы создали свой childDictionary с помощью:

NSMutableDictionary *childDictionary = [[NSMutableDictionary alloc] init];

, который возвращает объект с retainCount, равным 1, тогда вам нужно было бы сейчас отказаться от владения:

[childDictionary release];

Что касается кеша, вы, вероятно, захотите сохранить его в течение длительного времени: это, скорее всего, переменная экземпляра любого объекта, который управляет кешем, и он сбрасывается с помощью [cache removeAllObjects] при нажатии на предупреждение о памяти. 1038 *

Если вы разрабатываете на Mac с использованием сборки мусора, все это бесполезно. Но поскольку вы разговариваете по телефону, вам необходимо знать эти простые правила управления памятью. Мое объяснение действительно упускает из виду многие концепции, с которыми вы должны быть знакомы, поэтому я настоятельно рекомендую вам прочитать документацию Apple об этом .

0 голосов
/ 27 ноября 2010

Будет полезен упрощенный пример кода, демонстрирующий эту утечку.Только из вашего описания, возможно ли, что вызов, который вы используете для добавления imgData в словарь, сохраняет его?Если вы не сразу же выпустите imgData в своем собственном коде, у вас будет счетчик сохранения 2. Когда ваш локальный указатель imgData выйдет из области видимости, вы потеряете память.Это всего лишь удар в темноте без примера кода.

...