2011-09-20 6 views
0

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

-(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]; 
} 

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

EDIT:

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

-(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]; 

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

ответ

3

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

[UIView setAnimationDidStopSelector:@selector(playAnimation)]; 

Это будет цепь анимации в бесконечном цикле.

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

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

EDIT: Я забыл упомянуть, что вы должны назначить делегат анимации:

[UIView setAnimationDelegate:self]; //self or whatever implements playAnimation selector 
+1

И вы можете использовать '[UIView setAnimationDelay: 4.0]', чтобы получить 4-секундную паузу между повторами, которые у вас были с вашим методом. – morningstar

+0

Я пробовал то, что вы рекомендовали, но по какой-то причине анимация не зацикливается - она ​​воспроизводится только один раз. У меня есть '[UIView setAnimationDidStopSelector: @selector (commenceFishAnimation)];' в конце моего метода 'commenceFishAnimation'. – Snowman

+0

Я забыл упомянуть, что вам нужно назначить делегата анимации. [UIView setAnimationDelegate: self] Также убедитесь, что вы вызываете его перед вызовом [UIView commitAnimations]; – ender

1

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

[[[UIImageView alloc] init] retain]; 

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

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

Uh-oh, что случилось с предыдущим объектом, на который ссылается 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. Он может сказать вам, есть ли у вас утечки памяти и где они находятся.

Смежные вопросы