Почему я получаю EXC_BAD_ACCESS в селекторе NSTimer?

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

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} элементов в словаре не вызывается. Все кажется в порядке. Кроме того, что еще хуже, это работает для некоторых предметов.

Итак, мне интересно, есть ли проблема с потоками? или что-то еще непонятное?

Стек вызовов довольно прост:

#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: вы правы насчет стека вызовов, я совершил огромную ошибку. Это должен быть метод таймера, а не функция. Я просто исправляю это. Извините за ошибку. Но к вашему сведению, сигнатура метода:

- (bool)update;

person Sauleil    schedule 27.05.2010    source источник
comment
Существует несоответствие между вызовом метода функции и трассировкой стека, где есть functionm:. Это нормально ? Можете ли вы также опубликовать соответствующий код?   -  person Laurent Etiemble    schedule 27.05.2010
comment
@Laurent +около миллиона за публикацию соответствующего кода   -  person JeremyP    schedule 27.05.2010
comment
@AngeDeLaMort: несколько вопросов: что вы подразумеваете под селектором timerRefresh? В NSTimer такого селектора нет. В вашей трассировке стека нет timerRefresh. Где взять список ключей? Пожалуйста, опубликуйте код инициализации и планирования таймера в цикле выполнения и что происходит, когда таймер срабатывает.   -  person JeremyP    schedule 27.05.2010
comment
Можете ли вы опубликовать определение метода функции. Из трассировки стека он ожидает один параметр, но вы его не передаете.   -  person Laurent Etiemble    schedule 27.05.2010
comment
Меняется ли словарь, пока таймер активен?   -  person Georg Fritzsche    schedule 27.05.2010
comment
@Georg: нет, словарь не меняется.   -  person Sauleil    schedule 27.05.2010


Ответы (1)


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

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

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

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

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

person Sauleil    schedule 27.05.2010
comment
Если вы хотите получить дату прямо сейчас, вы можете просто сделать now = [NSDate date]; - person JeremyP; 27.05.2010