Утечка памяти в NSEnumerator - PullRequest
1 голос
/ 21 марта 2011

Это течет как безумный, из-за того, как я использую счетчики. Зачем? Утечка становится еще более серьезной, если я не освобождаю счетчик - я так понимаю ... но я не понимаю, почему он все еще протекает.

#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;
}

Ответы [ 2 ]

4 голосов
/ 21 марта 2011

Сам по себе не протекает - и вы не должны выпускать перечислитель.

Утечка памяти - это когда память оставлена ​​выделенной, но больше не может быть освобождена (обычно потому, что у вас больше нет указателя на нее). В этом случае перечислитель будет освобожден, когда пул автозапуска истощится, но вы не позволяете программе достичь этой строки с помощью цикла. Вот почему счетчики накапливаются. Если вы измените цикл на:

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

вы обнаружите, что потребление памяти остается постоянным, потому что перечислитель будет правильно освобождаться в конце каждой итерации.

0 голосов
/ 21 марта 2011

Он протекает, потому что ваш самый внешний пул авто-релизов может выполнить свое действие только один раз.Любые автоматически выпущенные объекты, созданные в цикле while (1), будут просто сидеть и потреблять память, пока поток вашей программы не доберется до [истечения пула] в конце.

Чтобы избежать этого, создайте дополнительные вложенные пулы автоматического выпуска в вашем цикле, например так:

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

Этот подход аналогичен тому, как работает AppKit, создавая и истощая новый пул автоматического выпуска для каждой итерации через свой цикл событий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...