Странная проблема выпуска - PullRequest
0 голосов
/ 14 ноября 2010

У меня странная проблема, но я совершенно уверен, что для вас это не так. Если это так, пожалуйста, помогите мне или объясните. У меня есть массив из 39 UIImages, которые будут использоваться для анимации UIImageView. и после воспроизведения анимации память не освобождается.

- (void)viewDidLoad {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    NSMutableArray* actionArray = [[NSMutableArray alloc]initWithCapacity:38];

    for (int i=1; i<=39; i++) {
        NSString* path = [[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"bg_Level1_%.4d", i] ofType:@"png"];
        UIImage *image = [[UIImage alloc]initWithContentsOfFile:path];
        [path release];
        [actionArray addObject:image];
        [image release];
        NSLog(@"path rc %d image %d", [path retainCount], [image retainCount]); 
    }
    imageView.animationImages = actionArray;
    imageView.animationDuration = 4.0;
    imageView.animationRepeatCount = 1;
    [imageView startAnimating];
    NSLog(@"RetainCount ActArr %d ImageView %d", [actionArray retainCount], [imageView retainCount]);
    [actionArray release];
    [pool drain];
    [imageView release];
    [self performSelector:@selector(playAnimation2) withObject:self afterDelay:5.0];
    [super viewDidLoad];
}

-(void)playAnimation2{
    if ([imageView isAnimating]) {
        [imageView stopAnimating];
    }
    NSLog(@"RetainCount ImageView %d",[imageView retainCount]);
}

утечек не обнаружено, но объем выделенной памяти по-прежнему составляет 24 МБ.

или это не так нужно?

EDIT:

Извините, моя вина. Из-за многих изменений в моем коде я потерялся в нем. После анализа я понял! Большое спасибо!

Правильный код:

- (void)viewDidLoad {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    NSMutableArray* actionArray = [[NSMutableArray alloc]initWithCapacity:38];

    for (int i=1; i<=39; i++) {
        NSString* path = [[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"bg_Level1_%.4d", i] ofType:@"png"];
        UIImage *image = [[UIImage alloc]initWithContentsOfFile:path];
//      [path release];
        [actionArray addObject:image];
        [image release];
        NSLog(@"path rc %d image %d", [path retainCount], [image retainCount]); 
    }
    imageView.animationImages = actionArray;
    imageView.animationDuration = 4.0;
    imageView.animationRepeatCount = 1;
    [imageView startAnimating];
    NSLog(@"RetainCount ActArr %d ImageView %d", [actionArray retainCount], [imageView retainCount]);
    [actionArray release];
    [pool drain];
    [self performSelector:@selector(playAnimation2) withObject:self afterDelay:5.0];
    [super viewDidLoad];
}

-(void)playAnimation2{
    if ([imageView isAnimating]) {
        [imageView stopAnimating];
    }
    [imageView removeFromSuperview];
    imageView.animationImages = nil;
    NSLog(@"RetainCount ImageView %d",[imageView retainCount]);
}

Проблема была с [path release];

Ответы [ 4 ]

6 голосов
/ 14 ноября 2010

В этом коде много неправильных вещей. Это чудо, что оно вообще работает.

Во-первых:

Не использовать -retainCount.

Абсолютный счет удержания объекта не имеет смысла.

Вы должны вызывать release ровно столько раз, сколько вы вызывали сохранение объекта. Не меньше (если вам не нравятся утечки) и, конечно же, не более (если вам не нравятся сбои).

Подробнее см. Руководство по управлению памятью .

<Ч />

Теперь некоторые проблемы:

  • Вы спросили, нужно ли очищать массив, а затем ответили array = nil; ... не работает . Установка ссылки на массив на nil ничего не делает с массивом; не освобождает или очищает это.

  • вы перевыпускаете path

  • вы загружаете серию изображений, вставляя их в массив, и в этом коде нет ничего, что освобождает массив (или очищает его). То, что ваше приложение продолжает использовать память и не показывает утечки, звучит как правильное поведение.

  • Почему вы выпускаете imageView? В этом коде нет ничего, что подразумевало бы, что вы сохранили его, и даже если бы оно было сохранено с помощью какого-то другого механизма (IB?), Это было бы действительно странным местом для его освобождения.

1 голос
/ 14 ноября 2010

Вы выпускаете imageView, не сохраняя его нигде, так что, вероятно, что-то не так с вашим кодом.Однако, похоже, что imageView сохраняется другим объектом (скорее всего, суперпредставлением), который хранит его в памяти.Это также сохранит массив изображений в памяти.

Если вам больше не нужно imageView, удалите его из родительского элемента с помощью [imageView removeFromSuperview];

1 голос
/ 14 ноября 2010

Как мы уже решили здесь: разрешение проблем

Установка imageView.animationImages = nil;

Кроме того, вам необходимо удалить [path release];, иначе произойдет сбой.

Руководство по управлению памятью - жизненно важное место для начала.

Редактировать Никогда не полагаться на свойство retainCount!

Редактировать 2 Выпуск imageView в этом методе также явно является ошибкой!

1 голос
/ 14 ноября 2010

Я думаю, вам нужно удалить все объекты из массива, чтобы он работал.

Попробуйте удалить объекты из массива, а затем массив, как только вы закончите с ними.

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