Почему я получаю EXC_BAD_ACCESS в селекторе NSTimer? - PullRequest
1 голос
/ 27 мая 2010

У меня довольно странная проблема. Для краткости напишу псевдокод:

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

@ Лоран: Это опечатка, когда я переписываю фактическое значение в соответствии с моим примером. (Фиксированный)

@ Джереми: Я постараюсь опубликовать некоторый код, чтобы помочь. Код был упрощен.

Таймер инициализации + функция обновления:

_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 ---

@ Лоран: вы правы насчет звонка, я допустил огромную ошибку. Это должен быть метод таймера, а не функция. Я просто исправляю это. Извините за ошибку. Но, к вашему сведению, подпись метода:

- (bool)update;

1 Ответ

0 голосов
/ 27 мая 2010

Кажется, я наконец-то нашел, в чем была проблема. В методе «обновление»

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

Проблема заключалась в том, что я не сделал сохранение даты (создания) в init. Я не очень понимаю, почему объект «поврежден», но я думаю, что отладчик должен был указывать на эту переменную, а не на вызов функции ...

Я позволю приложению какое-то время работать, чтобы посмотреть, прошел ли сбой.

Спасибо за помощь.

...