好的,这是我得到的错误:
-[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操作只是设置了一些变量,对定时器或waitingOpponentTimer没有任何作用。
我已经尝试了以下所有IF语句,以防止达到invalidate语句:
if (waitingOpponentTimer) {
if ([waitingOpponentTimer retainCount] > 0) {
if (waitingOpponentTimer.isValid) {
if (waitingOpponentTimer != nil) {
但是在所有情况下,它仍然通过IF语句,然后使用invalidate语句导致崩溃。
所以我的问题是,为什么/如何在对象isValid并且不是nil并且它的retainCount大于零时导致错误的无效?
是否有其他方法可以检查此项以防止无效到达?
我是iphone编程的完整菜鸟,花了几个小时谷歌搜索试图解决这个问题,但无法弄清楚我做错了什么。任何帮助和建议赞赏!
编辑: 只是为了澄清,我使用它在运行之前手动停止计时器。我知道如果它用完了,它会使自身无效,这就是为什么我使用IF语句来检查它是否已经失效(但它不起作用)。所以我认为当这次崩溃发生时,计时器已经自动失效,但我如何检查它是否已经失效?
编辑: 好的,我在下面标出了正确答案。我不知道在没有保留定时器并且已经使自身无效的情况下,实际上有没有理由通过IF语句获取代码,但是如果要在IF语句中使用定时器,则总是使用RETAIN
以下是相关信息:Is there any reason to retain a scheduled NSTimer if you don't need to invalidate it?
答案 0 :(得分:6)
你使用ARC吗?
waitingOpponentTimer = [[NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(waitingOpponentTimeOut)userInfo:nil repeats:NO] retain];
答案 1 :(得分:1)
尝试在启动计时器之前调用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];
}
答案 2 :(得分:0)
最有可能的是,您不需要使计时器无效。由于计时器不重复,一旦分配的时间到达结束,它将自动失效。这也可能是应用程序崩溃的原因。如果计时器已到达其运行结束,它会向自身发送无效消息,因此当您稍后调用它时,它不知道该怎么做,因为它已经失效。所以我的建议是忽略失效,因为它会处理自己(只要它不重复)