为什么我在NSTimer选择器中获得EXC_BAD_ACCESS?

时间:2010-05-27 14:06:49

标签: iphone objective-c nstimer exc-bad-access

我有一个非常奇怪的问题。为了简短起见,我会写一些伪代码:

init: create a dictionary and insert n elements.
      create a "repeat timer" and add it to the currentRunLoop using the timerRefresh selector.

timerRefresh: using a list of keys, find the items in the dictionary
              if the item exists -> call a function

所以,由于一个未知的原因,当我这样做时,我得到一个EXC_BAD_ACCESS:

    [item function];

但是我跟踪了从字典项中得到的地址,没关系。字典中项目的引用计数仍为1.不调用字典中项目的{release,dealloc}。一切似乎都很好。此外,为了使它最糟糕,它适用于某些项目。

所以,我想知道是否存在线程问题?还是其他一些模糊不清的东西?

callstack非常简单:

#0  0x93e0604b in objc_msgSend_fpret
#1  0x00f3e6b0 in ??
#2  0x0001cfca in -[myObject timerRefresh:] at myObject.m:000
#3  0x305355cd in __NSFireTimer
#4  0x302454a0 in CFRunLoopRunSpecific
#5  0x30244628 in CFRunLoopRunInMode
#6  0x32044c31 in GSEventRunModal
#7  0x32044cf6 in GSEventRun
#8  0x309021ee in UIApplicationMain
#9  0x000027e0 in main at main.m:14

所以,任何建议去哪里都会受到赞赏。

---编辑#1 ---

@Laurent:我改写实际值以符合我的例子是一个错字。 (固定)

@Jeremy:我会尝试发布一些代码来提供帮助。代码已经简化。

定时器初始化+刷新功能:

_refreshTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:5] interval:5
                                 target:self selector:@selector(onTimerRefresh:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_refreshTimer forMode:NSDefaultRunLoopMode];

//...

 (void)onTimerRefresh:(NSTimer*)theTimer {
      // the actual code is here. I will rewrite it so it's simpler:
     for (MyKey key in keys) {
         MyObject* object = [dictionary objectForKey:key];
         if (object)
             [object function];
     }
 }

我希望它更清楚一点。

是的,我已经在我的“功能”中评论了所有内容,看起来它并没有崩溃。我会让它运行一点但我没有做任何特殊的功能(与内存相关)。只是更新一些枚举值。

---编辑#2 ---

@Laurent:你对callstak说得对,我犯了一个大错。它应该是计时器方法而不是功能。我只是解决它。抱歉这个错误。但是,仅供参考,方法签名是:

- (bool)update;

1 个答案:

答案 0 :(得分:0)

我想我终于找到了问题所在。在方法“更新”

- (bool)update {
    // ...
    NSDate* now = [NSDate dateWithTimeIntervalSinceNow:0];
    NSTimeInterval interval = [now timeIntervalSinceNow] - [creation timeIntervalSinceNow];
    //...
}

问题是我没有在init中的日期(创建)上保留。我真的不明白为什么对象被“损坏”,但我认为调试器应该指向该变量而不是函数调用...

我会让应用程序运行一段时间以查看崩溃是否消失。

感谢您的帮助。