寻找有关动画完成后如何清理的反馈后,我实现了以下内容:
- (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版本];崩溃停止了(但显然开始了一些内存泄漏。)。
关于动画和从后台进入/重新打开应用程序,我是否容易误解?
我的猜测是,iOS进入后台后会自动清理进行中的所有动画,并自动将其释放到每个动画中。如果是这种情况,我是否仅希望它们已被清理并在applicationDidBecomeActive中保留一个标志来绕过发行版?
编辑1
我已经读到onAnimationComplete上的完成标志将让我知道动画是否完成了它的完整动画。仅仅相信它如果还没有完成就已经被清理(从 super View 中删除并发布)就足够了吗?
编辑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];
}];
仍然存在与上述相同的行为。根据Edit 1,仅假设已完成的BOOL为否,是否已经将其清除(从superview +释放中删除)就足够了吗?
任何信息都将不胜感激。
拉尔夫
最佳答案
首先,请不要在对象上使用大写字母-将其保留为类(对于我们大多数人来说,阅读代码会更加困难)。
通常,在回调中释放对象是一种不好的做法。使用分派(dispatch)块到主队列以释放对象或performSelectorOnMainthread:,看看是否有帮助。
编辑:并不意味着您需要一个完整的块。如果动画没有完成,再次阅读文档不会显示保留更改的迹象。由于您的代码中包含发行版,因此您没有使用ARC。
非ARC:因此imgStart是分配/初始化的,没有自动释放,因此它的保留计数为1。将其添加到 subview 中,现在是两个。您(或系统)将其从 subview 中删除,即现在为1。最终版本将其设置为0(我忽略了块本身的保留/释放)。我只是看不到系统如何释放它,因为它实际上不在可以看到的任何地方(它不是ivar,因此viewDidUnload无法释放它)。现在这是一个谜。
假设您已转换为ARC:imgStart在动画开始时发布,保留了两个内容,即 subview 数组和块。当将其从 subview 数组中移除(由任何人)时,保留计数将减少1,并且在块完成时也会将其释放,从而导致保留计数变为0从而将其释放。
如果上面没有任何提示或帮助,您至少可以尝试查找何时/何处释放该对象。在您的.m文件中创建UIImageView子类:
@implementation MyIV : UIIMageView
@end
@interface MyIV
- (void)dealloc
{
[super dealloc];
NSLog(@"MYIV DEALLOC!!!!");
}
@end
在日志消息上放置一个断点,您可以确切地看到它的解除分配位置。过去,我发现这很有用,我创建了一个ARC类,甚至对github上的类集Tracker都可以做到这一点。
关于iphone - 动画进入后台后使App崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16634595/