内存分配之谜与NSNumber盒装表达

时间:2014-07-16 14:58:35

标签: objective-c memory-management memory-leaks nsnumber

我有一个计算某些值的类,并提供这些值的字典作为返回值。字典在类的init中分配,并且每次算法运行时都会更新值。 return语句如下所示:

[self.retDict setObject:@(self.movmean) forKey:self.indexedKeys[0]];
[self.retDict setObject:@(self.movvar) forKey:self.indexedKeys[1]];
[self.retDict setObject:@(self.movstd) forKey:self.indexedKeys[2]];
...
[self.retDict setObject:@(0) forKey:self.indexedKeys[8]];
return self.retDict;

当我使用内存分配工具分析我的应用程序时,我看到非常严重的泄漏,追溯到这些行。深入研究调用树,我可以看到盒装表达式调用[NSNumber number numberWithdouble:](这非常有意义......)和[NSPlaceholdernumber initWithDouble:]。这反过来调用CFNumbercreate,似乎导致我的堆中CFNumber的数量似乎无限增长。

我想我的最终问题是,如果NSNumber盒装表达式可能导致未发布的CFNumber?或者如果我在上面的代码中做过的其他事情会导致这种情况?任何帮助解决这个问题将不胜感激。我经常在我的代码中使用盒装表达式,在运行大约10分钟后,我的应用程序累积了大约15MB的CFnumbers。

2 个答案:

答案 0 :(得分:2)

泄漏告诉你泄漏的物体在哪里被分配,而不是导致它泄漏的行为。

如果你在循环中这样做,那很可能是因为没有耗尽自动释放池。如果您使用@autoreleasepool { ... lines ... }包围上述行,则可能会解决问题。

如果确实是泄密,那么问题就出在其他地方。打开"跟踪引用计数" (原文如此)在分配工具中,它将向您展示额外保留的来源。

答案 1 :(得分:0)

在使用@autoreleasepool{}提到bbum之后,我做了一些研究并得出了答案。我正在处理的应用程序是我使用多线程的第一个应用程序。我们使用活动对象体系结构使用调度到自己的线程的多个对象。在活动对象的while循环中,我添加了一个@autoreleasepool {}(如下所示),并且所有内存泄漏都消失了。

while(!shutdown)
 @autoreleasepool{
  //do a bunch of work
  }
 }

我很惊讶地发现,即使启用ARC,当您分派新线程时,仍需要手动创建自动释放池。我在网上看到的关于这个问题的大多数答案都引用了iOS的旧版本,所以我想发布这个并确认它仍然是iOS 7.1中的情况。