2010-11-27 1 views
0

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

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

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

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

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

+0

Какую политику вы используете при загрузке данных? Вы подтвердили (то есть с утечками или распределениями), что память определенно просочилась или оставлена? – 2010-11-27 08:16:36

ответ

1

Способ управления памятью в 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]; 

Другим способом вы могли бы сделать это создать autoreleased версию объекта данных, а также добавить, что в dictioary.

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

1) Создание autoreleased 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], когда вы нажимаете предупреждение о памяти.

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

0

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

 Смежные вопросы

  • Нет связанных вопросов^_^