Iphone iOS-NSTimer-SIGABRT失效后-立即编辑DeAlloc Msg
我将NSTimer嵌入到一个播放图像序列的类中。基本上,它循环并更改UIImageView。如果我让图像序列完成,一切都会顺利,但是。。。如果我试图在计时器播放时停止计时,我会得到一个信号灯。编辑:不再是一个sigabrt,但现在是一个DeAlloc,我无法解释 帧序列末尾的“停止”与我称之为中间序列的停止相同 那么是什么导致NSTimer中断mid函数并解除锁定呢。更重要的是,我可以看些什么来修复它 谢谢 我在这里使用一些示例代码: 编辑:我将在此处添加我认为相关的代码 //调用此方法以启动动画Iphone iOS-NSTimer-SIGABRT失效后-立即编辑DeAlloc Msg,iphone,ios4,nstimer,sigabrt,Iphone,Ios4,Nstimer,Sigabrt,我将NSTimer嵌入到一个播放图像序列的类中。基本上,它循环并更改UIImageView。如果我让图像序列完成,一切都会顺利,但是。。。如果我试图在计时器播放时停止计时,我会得到一个信号灯。编辑:不再是一个sigabrt,但现在是一个DeAlloc,我无法解释 帧序列末尾的“停止”与我称之为中间序列的停止相同 那么是什么导致NSTimer中断mid函数并解除锁定呢。更重要的是,我可以看些什么来修复它 谢谢 我在这里使用一些示例代码: 编辑:我将在此处添加我认为相关的代码 //调用此方法以启动动
- (void) startAnimating
{
self.animationTimer = [NSTimer timerWithTimeInterval: animationFrameDuration target: self selector: @selector(animationTimerCallback:) userInfo: NULL repeats: TRUE];
[[NSRunLoop currentRunLoop] addTimer: animationTimer forMode: NSDefaultRunLoopMode];
animationStep = 0;
if (avAudioPlayer != nil)
[avAudioPlayer play];
// Send notification to object(s) that regestered interest in a start action
[[NSNotificationCenter defaultCenter]
postNotificationName:ImageAnimatorDidStartNotification
object:self];
}
- (void) animationTimerCallback: (NSTimer *)timer {
if (![self isAnimating])
return;
NSTimeInterval currentTime;
NSUInteger frameNow;
if (avAudioPlayer == nil) {
self.animationStep += 1;
// currentTime = animationStep * animationFrameDuration;
frameNow = animationStep;
} else {
currentTime = avAudioPlayer.currentTime;
frameNow = (NSInteger) (currentTime / animationFrameDuration);
}
// Limit the range of frameNow to [0, SIZE-1]
if (frameNow < 0) {
frameNow = 0;
} else if (frameNow >= animationNumFrames) {
frameNow = animationNumFrames - 1;
}
[self animationShowFrame: frameNow];
// animationStep = frameNow + 1;
if (animationStep >= animationNumFrames) {
[self stopAnimating];
// Continue to loop animation until loop counter reaches 0
if (animationRepeatCount > 0) {
self.animationRepeatCount = animationRepeatCount - 1;
[self startAnimating];
}
}
}
- (void) stopAnimating
{
if (![self isAnimating])
return;
[animationTimer invalidate];
self.animationTimer = nil;
animationStep = animationNumFrames - 1;
[self animationShowFrame: animationStep];
if (avAudioPlayer != nil) {
[avAudioPlayer stop];
avAudioPlayer.currentTime = 0.0;
self->lastReportedTime = 0.0;
}
// Send notification to object(s) that regestered interest in a stop action
[[NSNotificationCenter defaultCenter]
postNotificationName:ImageAnimatorDidStopNotification
object:self];
}
-(无效)开始初始化
{
self.animationTimer=[NSTimer timerWithTimeInterval:animationFrameDuration目标:self选择器:@selector(animationTimerCallback:)userInfo:NULL repeats:TRUE];
[[NSRunLoop currentRunLoop]addTimer:animationTimer forMode:NSDefaultRunLoopMode];
animationStep=0;
如果(avAudioPlayer!=nil)
[avAudioPlayer play];
//向在开始操作中重新设定兴趣的对象发送通知
[[NSNotificationCenter defaultCenter]
postNotificationName:ImageAnimatordStartNotification
对象:自我];
}
-(void)animationTimerCallback:(NSTimer*)计时器{
如果(![self isAnimating])
回来
NSTimeInterval当前时间;
现在就开始;
if(avAudioPlayer==nil){
self.animationStep+=1;
//currentTime=animationStep*animationFrameDuration;
frameNow=动画步骤;
}否则{
currentTime=avAudioPlayer.currentTime;
frameNow=(NSInteger)(当前时间/动画帧持续时间);
}
//将frameNow的范围限制为[0,大小为1]
if(frameNow<0){
frameNow=0;
}else if(frameNow>=动画numframes){
frameNow=animationNumFrames-1;
}
[自动画ShowFrame:frameNow];
//animationStep=frameNow+1;
如果(animationStep>=animationNumFrames){
[自动停止动画];
//继续循环动画,直到循环计数器达到0
如果(animationRepeatCount>0){
self.animationRepeatCount=animationRepeatCount-1;
[自启动];
}
}
}
-(无效)停止设置动画
{
如果(![self isAnimating])
回来
[动画计时器失效];
self.animationTimer=nil;
animationStep=animationNumFrames-1;
[自动画ShowFrame:animationStep];
如果(avAudioPlayer!=nil){
[avAudioPlayer停止];
avAudioPlayer.currentTime=0.0;
self->lastReportedTime=0.0;
}
//向在停止操作中重新登记兴趣的对象发送通知
[[NSNotificationCenter defaultCenter]
postNotificationName:ImageAnimatordStopNotification
对象:自我];
}
Edit2:所以我在Dealoc中注释掉了一个NSAssert,注释掉它会让我们了解更多。现在进入self.animationTimer=nil代码>并说***-ImageAnimator setAnimationTimer:::消息发送到解除分配的实例。
当我使计时器无效时,DeAlloc被正确调用。。。所以我在这里有点困惑。我有一个可行但不是最优的解决方案
我刚刚添加了另一个函数,将当前帧设置为最后一帧,并根据需要结束序列
但这并不能解决为什么它会这样做的问题,如果我试图中途停止序列,它会崩溃。好吧,我写了这段代码,所以我可以向您保证它应该工作得很好:)在使用视图之前,您需要调用stopAnimating,在dealloc中获得assert的唯一方法是在视图仍处于动画状态时取消分配视图。这是不应该发生的,这就是为什么会有断言的原因。还有一条大评论解释了这一断言,有什么不清楚的
- (void)dealloc {
// This object can't be deallocated while animating, this could
// only happen if user code incorrectly dropped the last ref.
NSAssert([self isAnimating] == FALSE, @"dealloc while still animating");
self.animationURLs = nil;
self.imageView = nil;
self.animationData = nil;
self.animationTimer = nil;
[super dealloc];
}
只要打电话:
[view stopAnimating];
在您从superview中删除视图之前,一切都会很好。如果您使用的是SIGABRT,则通常意味着您使用的是断言。查看日志以查看断言是什么。嗯,DeAlloc中有一个NSAssert。。。对这一点的评论更能说明问题。。。现在是“self.animationTimer=nil;”并说***-ImageAnimator setAnimationTimer:::消息发送到解除分配的实例。在我使计时器无效后,正在调用DeAlloc。。。所以我在这里有点困惑。你可能正在调用计时器-(void)animationTimerCallback:(NSTimer*)timer
,在你释放它之后…我明白了,我不知道如何阻止它发生。我调用stopAnimation命令,它进入该函数,它做的第一件事是点击invalidate,然后跳转到DeAlloc。当我调用stopAnimation时,我的应用程序是否可以调用animationTimerCallback?虽然您应该始终通过access访问IVAR,但DeAlloc是一个大的例外。在dealloc中直接释放您的IVAR。也就是说,此错误表明您在dealloc开始时调用[super dealloc](必须在结束时调用),或者self
已过度释放。