Остановить рекурсивную функцию на viewDidUnload - PullRequest
0 голосов
/ 20 сентября 2011

У меня есть рекурсивная функция, которая непрерывно воспроизводит анимацию UIView (если есть лучший способ сделать это, пожалуйста, дайте мне знать):

-(void)playAnimationRecursive
{
    [appDelegate commenceFishAnimation];
    [animationView addSubview:appDelegate.fishAnimationImageView];
    animationView.alpha=0.5;

    [NSTimer scheduledTimerWithTimeInterval:14.0 target:self selector:@selector(playAnimationRecursive) userInfo:nil repeats:NO];
}

и не уверен, что это необходимо, но вотappDelegate commenceFishAnimationMethod:

        upperFish=[[UIImageView alloc] initWithImage:upperFishImage];
        bigFish=[[UIImageView alloc] initWithImage:bigFishImage];
        shark=[[UIImageView alloc] initWithImage:sharkImage];
        groupFish=[[UIImageView alloc] initWithImage:groupFishImage];
        fish1=[[UIImageView alloc] initWithImage:fish1Image];
        fishAnimationImageView=[[[UIImageView alloc] init] retain];

        //set the initial position of each fish to be out of frame
        upperFish.frame=CGRectMake(-50, 150, 119/2, 93/2); //moves east
        bigFish.frame=CGRectMake(-280, 340, 251/2, 137/2); //moves east
        shark.frame=CGRectMake(-100, 390, 164/2, 52/2); //moves east
        groupFish.frame=CGRectMake(500, 320, 155/2, 89/2); //moves west
        fish1.frame=CGRectMake(370, 280, 155/2, 89/2); //moves west

        //add fishes to current view
        [fishAnimationImageView addSubview:upperFish];
        [fishAnimationImageView addSubview:bigFish];
        [fishAnimationImageView addSubview:shark];
        [fishAnimationImageView addSubview:groupFish];
        [fishAnimationImageView addSubview:fish1];

        //animate the position of each fish view
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:10.0];
        [UIView setAnimationCurve:UIViewAnimationCurveLinear];
        upperFish.transform=CGAffineTransformMakeTranslation(150, -200);
        bigFish.transform=CGAffineTransformMakeTranslation(600, 0);
        shark.transform=CGAffineTransformMakeTranslation(550, 0);
        groupFish.transform=CGAffineTransformMakeTranslation(-600, 0);
        fish1.transform=CGAffineTransformMakeTranslation(-550, 0);

        [UIView commitAnimations];
        [fishAnimationImageView release];
        [upperFish release];
        [bigFish release];
        [shark release];
        [groupFish release];
        [fish1 release];  
}

Итак, что происходит, так это то, что каждое мое представление воспроизводит эту анимацию в BG, поэтому, если я нахожусь на представлении A, тогда она вызывает рекурсивную функцию и воспроизводит анимацию непрерывно.Если я перехожу к представлению B, то он также вызывает рекурсивную функцию и непрерывно воспроизводит анимацию.Тем не менее, я получаю предупреждение памяти уровня 2, и я думаю, возможно, это потому, что представление A все еще вызывает рекурсивный метод?Если это причина, то как бы я остановил рекурсивный метод при выгрузке?Или это не моя проблема?

РЕДАКТИРОВАТЬ:

Вот мой код сейчас (анимация не зацикливается)

-(void)commenceFishAnimation
{
    UIImageView *newImageView=[[UIImageView alloc] init];
    self.fishAnimationImageView=newImageView;

    upperFish=[[UIImageView alloc] initWithImage:upperFishImage];
    bigFish=[[UIImageView alloc] initWithImage:bigFishImage];
    shark=[[UIImageView alloc] initWithImage:sharkImage];
    groupFish=[[UIImageView alloc] initWithImage:groupFishImage];
    fish1=[[UIImageView alloc] initWithImage:fish1Image];

    //set the initial position of each fish to be out of frame
    upperFish.frame=CGRectMake(-50, 150, 119/2, 93/2); //moves east
    bigFish.frame=CGRectMake(-280, 340, 251/2, 137/2); //moves east
    shark.frame=CGRectMake(-100, 390, 164/2, 52/2); //moves east
    groupFish.frame=CGRectMake(500, 320, 155/2, 89/2); //moves west
    fish1.frame=CGRectMake(370, 280, 155/2, 89/2); //moves west

    //add fishes to current view
    [fishAnimationImageView addSubview:upperFish];
    [fishAnimationImageView addSubview:bigFish];
    [fishAnimationImageView addSubview:shark];
    [fishAnimationImageView addSubview:groupFish];
    [fishAnimationImageView addSubview:fish1];

    //animate the position of each fish view
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:10.0];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    upperFish.transform=CGAffineTransformMakeTranslation(150, -200);
    bigFish.transform=CGAffineTransformMakeTranslation(600, 0);
    shark.transform=CGAffineTransformMakeTranslation(550, 0);
    groupFish.transform=CGAffineTransformMakeTranslation(-600, 0);
    fish1.transform=CGAffineTransformMakeTranslation(-550, 0);

    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(commenceFishAnimation)];
    [UIView commitAnimations]; 

    [fishAnimationImageView release];
    [upperFish release];
    [bigFish release];
    [shark release];
    [groupFish release];
    [fish1 release];
    //[newImageView release]; //if I release it, then my animation doesn't play for some reason
}

Затем в каком-то другом классе в методе viewDidLoadЯ делаю это:

[appDelegate commenceFishAnimation];
[animationView addSubview:appDelegate.fishAnimationImageView];

Но анимация воспроизводится только один раз.

Ответы [ 2 ]

3 голосов
/ 20 сентября 2011

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

    [UIView setAnimationDidStopSelector:@selector(playAnimation)];

Это объединит вашу анимацию в бесконечный цикл.

Но также обратите внимание, что в вашем методе playAnimationRecursive вы добавляете подпредставления и планируете NSTimer каждые 14 секунд, не выпуская их. Это действительно плохая идея.

Подводя итог: забудьте о рекурсии и используйте метод выше.

РЕДАКТИРОВАТЬ: Я забыл упомянуть, что вы должны назначить делегата анимации:

[UIView setAnimationDelegate:self];  //self or whatever implements playAnimation selector
1 голос
/ 20 сентября 2011

Я вижу несколько красных флажков, которые указывают на то, что вы не очень хорошо понимаете подсчет ссылок в Задаче C.

[[[UIImageView alloc] init] retain];

Никогда не делай этого. alloc уже дает вам счетчик ссылок 1. Вам также не нужно сохранять его.

fishAnimationImageView=[[[UIImageView alloc] init] retain];

О-о, что случилось с предыдущим объектом, на который ссылается fishAnimationImageView? Это все еще сохраняется, но никто не имеет ссылки на него. Течь!

[fishAnimationImageView release];

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

Вот что вы должны сделать.

UIImageView *newFishAnimationImageView = [[UIImageView alloc] init];
// retain count = 1
self.fishAnimationImageView = newFishAnimationView;
// retain count = 2
// old value retain count = 0
// assuming a typical property declaration as retain, and setter made by @synthesize
[newFishAnimationView release];
// retain count = 1; not owned locally, but owned by your app delegate

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

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

Кроме того, попробуйте Product> Profile в XCode и выберите Leaks. Он может сказать вам, если у вас есть утечки памяти и где они находятся.

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