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];

在任何地方都没有其他等待OpponentTimer的情况,只有我上面显示的那些。waitingOpponentTimeOut操作只设置几个变量,对计时器或waitingOppenntTimer不做任何操作。

我已经尝试了以下所有IF语句,以防止到达无效语句:

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

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

所以我的问题是,当对象是Valid并且不是nil并且retainCount大于零时,为什么/如何使invalid导致错误?

是否有其他方法对此进行检查,以防止达到无效状态?

我完全不懂iphone编程,花了几个小时在谷歌上搜索,试图弄清楚这一点,但无法弄清楚我做错了什么。感谢您的帮助和建议!

编辑:只是为了澄清,我用这个来手动停止计时器运行之前。我知道,如果它用完了,它就会使自己失效,这就是为什么我使用if语句来检查它是否已经失效(但它不起作用)。所以我认为当这个崩溃发生时,计时器已经失效了,但我该如何检查它是否已经失效?

编辑:好的,我在下面标出了正确答案。我不知道当计时器没有被保留并且已经失效时,代码是否真的会通过if语句,但答案是,如果要在if语句中使用计时器,则始终使用RETAIN。

以下是相关信息:如果你不这样做,有什么理由保留预定的NSTimer吗;不需要使其无效吗?

您使用ARC吗?

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

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

这样你就不会意外地创建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]

仍然有一个定时器在浮动,如果它在你意想不到的时候启动,可能会引发问题。所以在称之为之前,我会测试一下isValid

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];
}

很可能,您不需要使计时器无效。由于计时器不重复,一旦分配的时间结束,它就会使自己失效。这也可能是应用程序崩溃的原因。如果计时器已经运行到结束,它会向自己发送失效消息,所以当您稍后调用它时,它不知道该怎么办,因为它已经失效了。因此,我的建议是忽略无效,因为它会自行处理(只要它不重复)

最新更新