我有一个连续播放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 beginFishAnimationMethod:
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];
但动画只播放一次。
答案 0 :(得分:3)
这不是链接动画的最佳方式,而是使用它:
[UIView setAnimationDidStopSelector:@selector(playAnimation)];
这将在无限循环中链接您的动画。
但请注意,在您的方法playAnimationRecursive
中,您每14秒添加一次子视图并安排NSTimer
而不释放它们。这是一个非常糟糕的主意。
总结:忘记递归并使用上面的方法。
编辑:我忘了提到你必须分配动画的代表:
[UIView setAnimationDelegate:self]; //self or whatever implements playAnimation selector
答案 1 :(得分:1)
我看到一些红色标记表明你对目标C中的引用计数没有很好的理解。
[[[UIImageView alloc] init] retain];
永远不要那样做。 alloc
已经为您提供了1的引用计数。您也不需要保留它。
fishAnimationImageView=[[[UIImageView alloc] init] retain];
哦,哦,fishAnimationImageView引用的上一个对象发生了什么?它仍然保留,但没有人提及它。泄漏!
[fishAnimationImageView release];
技术上正确,因为您之前将其保留了两次,但通常不应该释放该对象,因为它(我假设)是您的app委托的实例变量。
这是你应该做的。
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
通过属性引用事物通常可以获得正确的引用计数行为。遵循这一点,以及释放你分配的任何东西的规则,并且在很多情况下你会出错。
您应该查看有关引用计数的文档。
另外,试试产品>在XCode中配置文件,然后选择Leaks。它可以告诉您是否有内存泄漏以及它们的位置。