【问题标题】:Instruments (Leaks) and NSDateFormatter仪器(泄漏)和 NSDateFormatter
【发布时间】:2023-03-18 01:10:01
【问题描述】:

当我使用 Instruments Leaks 运行我的 iPhone 应用程序并使用 NSDateFormatter 解析一堆 NSDate 时,我的内存增加了大约 1mb 并保持不变,即使这些 NSDate 在解析后应该被释放(如果它们不是,我只是丢弃它们新)。

我认为 malloc(在下面我最重的堆栈跟踪中)可以成为 NSDate 的一部分,但我也认为它可能是仅在解析的某个中间步骤期间使用的内存。有谁知道它是哪一个或如何找出来?

另外,有没有办法在 NSDate dealloc 上设置一个断点来查看该内存是否真的被回收了?

这是我的日期格式化程序在解析这些日期时的样子:

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:]

谢谢!

【问题讨论】:

    标签: iphone objective-c memory-leaks malloc nsdateformatter


    【解决方案1】:
    [df setDateFormat:@"EEE, d MMM yyyy H:m:s z"]; // Remove the `z`
    

    当使用 z 选项时,在一次调用“dateFromString”后,868 Kb 将永久分配到 iPhone OS 2.2.1 或 3.1.2(未来更多)。

    包含源代码和日志文件的完整文章可以在以下位置阅读 http://thegothicparty.com/dev/article/nsdateformatter-memory-leak/

    【讨论】:

      【解决方案2】:

      NSDateFormatter 解析带有时区的日期字符串可能存在问题,因为当我更改格式化程序模式以删除时区部分时,问题消失了。

      我从这里改变了它:

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

      到这里:

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

      但现在的问题是日期没有得到正确的时区,所以我必须自己确定时区。

      【讨论】:

      【解决方案3】:

      丢弃 NSDateFormatters 是什么意思?当你完成它们时你会释放它们吗?

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

      您的代码分配了内存,但您需要调用

      [df release];
      

      当你完成它们时。当你分配(或复制)对象时,它的引用计数加一。当您释放对象时(您向它发送release 消息),引用计数会减少一。当引用计数达到 0 时,对象被释放。

      如果您不发送release 消息,它将留在内存中并且您有内存泄漏。

      【讨论】:

      • 当我说我丢弃它们时,我指的是 NSDates。正如您从上面的堆栈跟踪中看到的那样,我正在使用 [NSDateFormatter dateFromString] 创建 NSDate 对象,这些对象以 malloc 调用结束,该调用显示在 Instruments 的最重堆栈跟踪中(顺便说一句,我为最重选择了“已创建且仍然存在”我发布的堆栈跟踪)。
      • 那么应该没有问题,dateFromString 会返回自动释放的对象。如果您正在创建许多自动释放的 NSDates,它们将一直存在,直到下一个偶数循环将被清理。这是因为自动释放的对象最终进入池中,该池在处理池结束时被清理,如果您创建大量日期,这可能会导致您的内存使用量激增。
      猜你喜欢
      • 2011-07-11
      • 2011-11-02
      • 2011-06-18
      • 2011-12-02
      • 2013-07-19
      • 2012-07-06
      • 2011-10-14
      • 1970-01-01
      相关资源
      最近更新 更多