Сбой памяти iPhone: сигнал 0 - PullRequest
1 голос
/ 24 марта 2011

Я разрабатываю приложение для iPhone, которое отображает некоторые плитки с карты.У меня есть поток, который загружает плитки из Интернета или файловой системы.Это бесконечный потокплитки загружаются как autorelease и nog автоматически выпускаются.

В основном я делаю это в моей бесконечной ветке:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
while( true ){
    UIImage * img = nil;
    NSFileHandle * tile = [NSFileHandle fileHandleForReadingAtPath:filePath];
    if( tile ){
        NSData * data = [tile readDataToEndOfFile];
        if( data ){
            img = [[UIImage alloc] initWithData:data];
            local = YES;
        }
    }
    if( img == nil ){
        NSURL * url = [NSURL URLWithString: [NSString stringWithFormat:@"http://tile.openstreetmap.org/%@.png", todoKey ] ];
        img = [[UIImage alloc] initWithData: [NSData dataWithContentsOfURL: url options:NSDataReadingMapped error:&error] ];
    }

    if( img != nil ){
        [cache addObject:img]; //cache is an array of tiles
    }

    [img release];
    [self cleanupCache]; //method to check if cache is full, and if so remove's objects from it
}
[pool release];

Я думаю, что autoreleasepool не очищает "мертвых"время от времени ссылки, и все плитки хранятся в памяти.Когда я проверяю утечки инструментов, нет никаких утечек памяти, но «живая память» продолжает накапливаться ..

Есть идеи, почему это происходит и как я могу предотвратить это?

Ответы [ 3 ]

2 голосов
/ 24 марта 2011

Вы должны поменять местами первые 2 строки программы:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
while( true ){
  ...
  [pool release];
}

должно быть

while( true ){
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  ...
  [pool release];
}

В настоящее время, после первого обхода цикла, созданный вами NSAutoreleasePoolбыть выпущеным.После этого все автоматически выпущенные объекты будут добавлены в другой NSAutoreleasePool, более высокий в стеке вызовов.Я подозреваю, что этот родительский пул автоматического выпуска никогда не освобождается во время работы вашей программы.

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

Я исправил отступ в вашем коде, надеюсь, я правильно понял. Улучшенный отступ делает очевидной одну проблему:

Вы отпускаете уже освобожденный объект, ваш пул.

Попробуйте переместить NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; внутрь цикла.

Но, скорее всего, вы должны сначала избавиться от петли.

Другая проблема в том, что вы не устанавливаете img в ноль. Если в первом запуске цикла допустим img, код будет считать его действительным для всех последующих циклов. Если вы удаляете img где-то из кэша (и объект, на который указывает img, освобождаются), вы отправляете retain в освобожденный объект, когда пытаетесь добавить его в кеш.

Добавьте img = nil; в начале вашего цикла.

0 голосов
/ 24 марта 2011
if( img != nil ){
 [cache addObject:img];

cache по-прежнему содержит ссылку на все объекты, которые вы добавили.Вы, вероятно, должны удалить объекты, которые вы не будете использовать.

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