iPhone崩溃 – 消息发送到解除分配的实例

好的,这是我得到的错误:

-[CFRunLoopTimer invalidate]: message sent to deallocated instance 0x109b05a0 (gdb) 

这是导致崩溃的代码:

  if (waitingOpponentTimer) { [waitingOpponentTimer invalidate]; //<-- Crash/error occurs here waitingOpponentTimer = nil; } 

和其他地方:

  NSTimer* waitingOpponentTimer; 

并且:

  waitingOpponentTimer = [NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(waitingOpponentTimeOut)userInfo:nil repeats:NO]; 

WaitOpponentTimer没有任何其他的发生,只有我上面显示的那些。 waitingOpponentTimeOut动作只是设置一些variables,对定时器或waitOpponentTimer没有任何作用。

我已经尝试了所有下面的IF语句来防止无效声明:

  if (waitingOpponentTimer) { if ([waitingOpponentTimer retainCount] > 0) { if (waitingOpponentTimer.isValid) { if (waitingOpponentTimer != nil) { 

但是,在所有情况下,它仍然通过IF语句,然后使用invalidate语句导致崩溃。

所以我的问题是,为什么/如何无效导致错误,当对象isValid,而不是零,它的retainCount大于零?

是否有另一种方法来检查,以防止无效达成?

我是一个完全noob iphone编程,花了几个小时谷歌尝试找出这个,但无法弄清楚我做错了什么。 任何帮助和build议表示赞赏!

编辑:只是为了澄清,我用它来手动停止计时器运行之前。 我明白,如果它用完了,它自己失效,这就是为什么我使用IF语句来检查它是否已经失效(但它不工作)。 所以我觉得这个崩溃发生的时候计时器已经失效了,但是如何检查它是否已经失效?

编辑:好吧我标记下面的正确答案。 我不知道当定时器没有被保留并且已经使自己失效的时候,为什么代码通过IF语句得到的实际上是有原因的,但是如果你打算在IF语句中使用定时器的话,答案总是使用RETAIN 。

这里是相关的信息: 如果你不需要使NSTimer失效,是否有任何理由保留预定的NSTimer?

你用ARC吗?

 waitingOpponentTimer = [[NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(waitingOpponentTimeOut)userInfo:nil repeats:NO] retain]; 

尝试在启动计时器之前调用isValid

这样你不能无意中创build它的2个实例

想想这个

  waitingOpponentTimer = [NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(waitingOpponentTimeOut)userInfo:nil repeats:NO]; waitingOpponentTimer = [NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(waitingOpponentTimeOut)userInfo:nil repeats:NO]; [waitingOpponentTimer invalidate] 

还有一个计时器在周围浮动,如果它发生,当你不期望它会导致问题。 所以遐,我会在调用之前testingisValid

 if ([waitingOpponentTimer isValid] { [waitingOpponentTimer invalidate] waitingOpponentTimer = [[NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(waitingOpponentTimeOut)userInfo:nil repeats:NO] retain]; }else{ waitingOpponentTimer = [[NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(waitingOpponentTimeOut)userInfo:nil repeats:NO] retain]; } 

最有可能的是,你不需要使计时器无效。 由于定时器不重复,一旦分配的时间到达终点,它将自动失效。 这也可能是应用程序崩溃的原因。 如果计时器已经到达运行的末尾,它将自己发送无效的消息,所以当你稍后调用它时,它不知道该做什么,因为它已经失效了。 所以我的build议是忽略无效,因为它会处理自己(只要它是不重复的)