Search code examples
objective-cmemory-managementmemory-leaksnsnumber

Memory Allocation Mystery with NSNumber boxed expression


I have a class which calculates some values, and provides a dictionary of those values as the return. The dictionary is allocated in the init of the class, and the values updated every time the algorithm runs. the return statement looks like this:

[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;

When I profile my app with the memory allocations tool, I see very substantial leak that traces down to these lines. Delving deeper into the call tree I can see that the boxed expression calls [NSNumber number numberWithdouble:] (which makes perfect sense...) and [NSPlaceholdernumber initWithDouble:]. This in turn calls CFNumbercreate, and seems to lead to the number of CFNumber's in my heap appearing to grow unbounded.

I suppose my ultimate question is if a NSNumber boxed expression could lead to a unreleased CFNumber? or if something else that I've done in the above code would lead to that? Any help resolving this issue would be greatly appreciated. I use boxed expressions quite often in my code, and after running for only about 10 minutes my app has almost 15MB of CFnumbers accumulated.


Solution

  • Leaks tells you where an object that was leaked was allocated, not the action that caused it to leak.

    If you are doing this in a loop, then it is most likely because of the lack of draining an autorelease pool. If you were to surround the above lines with @autoreleasepool { ... lines ... }, it may fix the problem.

    If it is truly a leak, then it the problem lies elsewhere. Turn on "track reference counts" (sic) in the Allocations Instrument and that'll show you where the extra retains are coming from.