NSEnumerator memory leak

ε祈祈猫儿з 提交于 2019-12-24 07:18:16

问题


This leaks like mad, due to the way I use enumerators. Why? It leaks even more severely if I don't release the enumerator - I understand that much.. but I don't understand why this still leaks.

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

   // insert code here...
   NSLog(@"Hello, World!");

   // Create an array and fill it with important data!  I'll need to enumerate this.
   NSMutableArray *myArray = [[NSMutableArray alloc] initWithCapacity:300];

   int i;
   for(i = 0; i < 200; i++)
     [myArray addObject:[NSNumber numberWithInt:i]];

   while(1)
   {
      NSEnumerator *enumerator = [myArray objectEnumerator];
      // Imagine some interesting code here
      [enumerator release];
   }

   // More code that uses the array..

   [pool drain];
   return 0;
}

回答1:


It doesn't leak, per se — and you shouldn't release the enumerator.

A memory leak is when memory is left allocated but can no longer be released (typically because you no longer have a pointer to it). In this case, the enumerator will be released when the autorelease pool drains, but you're preventing the program from reaching that line with your loop. That's why the enumerators pile up. If you change the loop to:

while(1)
{
    NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init];
    NSEnumerator *enumerator = [myArray objectEnumerator];
    [innerPool drain];
}

you'll find that your memory consumption remains constant, because the enumerator will be properly released at the end of each iteration.




回答2:


It leaks because your outermost autorelease pool only gets to do its thing once. Any autoreleased objects created within the while(1) loop will just sit around consuming memory until your program flow gets to the [pool drain] at the end.

To avoid this, create additional nested autorelease pools inside your loop, like this:

while(1) {
    NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init];
    // .. Do a bunch of stuff that creates autoreleased objects
    [innerPool drain];
}

This approach is similar to how AppKit works, creating and draining a new autorelease pool for each iteration through its event loop.



来源:https://stackoverflow.com/questions/5383463/nsenumerator-memory-leak

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!