Вопрос по memory-leaks, nsdateformatter, iphone, malloc, objective-c – Инструменты (утечки) и NSDateFormatter

4

Когда я запускаю приложение для iPhone с Instruments Leaks и анализирую множество NSDates с использованием NSDateFormatter, моя память увеличивается примерно на 1 МБ и остается, даже если эти NSDate должны быть освобождены после анализа (я просто отбрасываю их, если они не новые).

Я думал, что malloc (в моей самой тяжелой трассировке стека ниже) может стать частью NSDate, но я также подумал, что это может быть память, которая используется только на каком-то промежуточном этапе синтаксического анализа. Кто-нибудь знает, какой это или как узнать?

Кроме того, есть ли способ поставить точку останова на NSDate Deloc, чтобы увидеть, действительно ли эта память восстанавливается?

Вот как выглядит мой форматировщик даты для разбора этих дат:

df = [[NSDateFormatter alloc] init]; 
[df setDateFormat:@"EEE, d MMM yyyy H:m:s z"];

Вот самая тяжелая трассировка стека, когда память поднимается и остается там:

   0 libSystem.B.dylib  208.80 Kb     malloc
   1 libicucore.A.dylib  868.19 Kb     icu::ZoneMeta::getSingleCountry(icu::UnicodeString const&, icu::UnicodeString&)
   2 libicucore.A.dylib  868.66 Kb     icu::ZoneMeta::getSingleCountry(icu::UnicodeString const&, icu::UnicodeString&)
   3 libicucore.A.dylib  868.67 Kb     icu::ZoneMeta::getSingleCountry(icu::UnicodeString const&, icu::UnicodeString&)
   4 libicucore.A.dylib  868.67 Kb     icu::DateFormatSymbols::initZoneStringFormat()
   5 libicucore.A.dylib  868.67 Kb     icu::DateFormatSymbols::getZoneStringFormat() const
   6 libicucore.A.dylib  868.67 Kb     icu::SimpleDateFormat::subParse(icu::UnicodeString const&, int&, unsigned short, int, signed char, signed char, signed char*, icu::Calendar&) const
   7 libicucore.A.dylib  868.67 Kb     icu::SimpleDateFormat::parse(icu::UnicodeString const&, icu::Calendar&, icu::ParsePosition&) const
   8 libicucore.A.dylib  868.67 Kb     icu::DateFormat::parse(icu::UnicodeString const&, icu::ParsePosition&) const
   9 libicucore.A.dylib  868.67 Kb     udat_parse
  10 CoreFoundation  868.67 Kb     CFDateFormatterGetAbsoluteTimeFromString
  11 CoreFoundation  868.67 Kb     CFDateFormatterCreateDateFromString
  12 Foundation  868.67 Kb     -[NSDateFormatter getObjectValue:forString:range:error:]
  13 Foundation  868.75 Kb     -[NSDateFormatter getObjectValue:forString:errorDescription:]
  14 Foundation  868.75 Kb     -[NSDateFormatter dateFromString:]

Спасибо!

Ваш Ответ

3   ответа
0

Что вы имеете в виду, отбрасывая NSDateFormatters? Вы отпускаете их, когда закончите с ними?

df = [[NSDateFormatter alloc] init]; // allocates memory

Ваш код выделяет память, но вам нужно позвонить

[df release];

когда вы закончите с ними. Когда вы выделяете (или копируете) объект, его счетчик ссылок увеличивается на единицу. Когда вы отпускаете объект (вы отправляетеrelease сообщение ему) счетчик ссылок уменьшается на единицу. Когда счетчик ссылок достигает 0, объект освобождается.

Если вы не отправили егоrelease сообщение останется в памяти, и у вас утечка памяти.

Тогда не должно быть проблем, dateFromString вернет автоматически освобожденный объект. Если вы создаете много автоматически выпущенных NSDates, они будут зависать до следующего четного цикла, где они будут очищены. Это связано с тем, что автоматически выпущенные объекты попадают в пул, который очищается в конце даже пула обработки, если вы создаете много дат, это может привести к увеличению использования вашей памяти.
Я ссылался на NSDates, когда сказал, что отказываюсь от них. Как вы можете видеть из моего стека трассировки выше, я использую [NSDateFormatter dateFromString] для создания объектов NSDate, который заканчивается вызовом malloc, который отображается в самой тяжелой трассировке стека из инструментов (кстати, я выбрал "Создан и еще жив" для самый тяжелый след стека, который я отправил). Cal
1

Может быть проблема с анализом строк даты NSDateFormatter с часовыми поясами, потому что, когда я изменил шаблон форматирования, чтобы удалить часть часового пояса, проблема исчезла.

Я изменил это из этого:

[df setDateFormat:@"EEE, d MMM yyyy H:m:s z"];

К этому:

[df setDateFormat:@"EEE, d MMM yyyy H:m:s"];

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

Об этом есть в списке рассылки Cocoa-dev:lists.apple.com/archives/Cocoa-dev/2009/Apr/msg01913.html
3
[df setDateFormat:@"EEE, d MMM yyyy H:m:s z"]; // Remove the `z`

868 Кбайт будут постоянно выделяться на iPhone OS 2.2.1 или 3.1.2 (в будущем) после одного вызова «dateFromString» когда используется опция z.

Полный текст статьи с исходным кодом и файлом журнала можно прочитать по адресу http://thegothicparty.com/dev/article/nsdateformatter-memory-leak/

Похожие вопросы