在完成关于如何清理动画的反馈后,我实施了以下内容;
- (void)onAnimationComplete:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
UIImageView *AnimationImageEnd = context;
[AnimationImageEnd removeFromSuperview];
[AnimationImageEnd release];
}
并将它们设置为关闭(我删除了一些帧和旋转计算);
UIImageView * AnimationImageStart = [[UIImageView alloc] initWithImage: AnimationImage];
[self addSubview:AnimationImageStart];
[UIView beginAnimations:nil context:AnimationImageStart];
[UIView setAnimationDuration:iSpeed];
AnimationImageStart.transform = transform;
[UIView setAnimationDidStopSelector:@selector(onAnimationComplete:finished:context:)];
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
这似乎工作正常,并在动画完成后清理所有已用内存。
自从实施这种方法以来,如果动画已经预先启动,我现在遇到了重新打开应用程序的问题。该应用程序现在崩溃,出现以下错误;
*** -[UIImage _isDecompressing]: message sent to deallocated instance 0x21083ad0
我有一个修补程序,它似乎完全取决于使用的版本。如果我删除[AnimationImageEnd release];崩溃停止(但它显然会启动一些内存泄漏..)。
是否有一些简单的事情我误解了动画和应用程序从后台进入/重新开放?
我的猜测是iOS会在进入后台后自动清理正在进行的任何动画,并自动将释放发送到每个动画。如果是这种情况,我应该只是简单地期望它们已被清理并在applicationDidBecomeActive中保留一个标志以绕过该版本吗?
修改1 我已经读过onAnimationComplete上的完成标志会让我知道动画是否完成了它的完整动画。是否足以相信如果它没有完成它已经被清理(从superview中删除并被释放)?
修改2
根据David的回复,我已将此更新为一个块;
[UIView animateWithDuration:5.0f
delay:0.0f
options:0
animations:^{
imgStart.frame = CGRectMake( 0, 0, 10.0f, 10.0f);
}
completion:^(BOOL finished){
[imgStart removeFromSuperview];
//This still crashes the App as soon as the App returns from being in the background
[imgStart release];
}];
仍然存在与上面详述的相同的行为。根据编辑1,是否足以假设每当完成的BOOL为NO时,它已经被清理(从superview +中删除)?
非常感谢任何信息。
拉尔夫
答案 0 :(得分:0)
首先,请不要使用对象的首字母大写字母 - 为类保留它们(这使得我们大多数人阅读代码变得更加困难)。
通常,在回调中释放对象是不好的做法。使用主队列的调度块来释放对象或performSelectorOnMainthread:,看看是否有帮助。
编辑:并不意味着暗示你需要完整的阻止。如果动画没有完成,再次阅读文档并不表示保留更改。由于您的代码中有一个版本,因此您没有使用ARC。非ARC:所以imgStart是alloc / inited,没有自动释放,所以它的保留计数是1.你将它添加到子视图,它现在是两个。您(或系统)将其从子视图中删除,现在为1.最终版本使其为0(我忽略了块本身的保留/释放)。我只是无法看到系统如何释放它,因为它不是它可以看到的任何地方(它不是一个ivar,所以viewDidUnload无法释放它)。现在这是一个谜。
假设你转换为ARC:imgStart在动画开始时被释放,两个东西保留它,子视图数组和块。当它从子视图数组中删除时(由who who),保留计数减少1,当块完成时它也将释放它,导致保留计数变为0,因此它将被释放。
如果上面没有任何铃声或帮助,你至少可以尝试找到该对象被取消分配的时间/地点。在.m文件中创建一个UIImageView子类:
@implementation MyIV : UIIMageView
@end
@interface MyIV
- (void)dealloc
{
[super dealloc];
NSLog(@"MYIV DEALLOC!!!!");
}
@end
在日志消息上放置一个断点,您可以确切地看到它被取消分配的确切位置。我发现这在过去非常有帮助我创建了一个ARC类,即使对于github上的类集群,也称为Tracker。