BAD_ACCESS при вызове ручки таймера - PullRequest
2 голосов
/ 04 октября 2011

У меня есть реализация таймера в Timer.h / .mm

@implementation Timer

static multiset<Timer *> timers;

- (void) run
{
    action();

    if (!repeat) 
    {
        timers.erase(timers.find(self));
    }
}

+ (void) run: (Action) action after: (int) seconds repeat: (bool) rep
{
    Timer * timer = [[Timer alloc] init];

    timer->action = action;
    timer->repeat = rep;

    [NSTimer scheduledTimerWithTimeInterval:seconds
                                     target:timer
                                   selector:@selector(run)
                                   userInfo:nil
                                    repeats:rep];

    // timers.insert(timer);       // ANY version will fail
    timers.insert([timer retain]);
}

@end

После этого я вызываю его из своего UIViewController.mm:

[Timer run:^ 
{ 
    // some code...
}
after:2];

Но он падает сEXC_BAD_ACCESS, когда пришло время без ввода [Запуск таймера]!

#0  0x00000020 in ??
#1  0x000b87a5 in __NSFireTimer
#2  0x00dfafe3 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__

Что я делаю не так?Почему он называет cs: 20h?У меня вообще нет такого значения (32) в моей программе!

После некоторых незначительных изменений таймер пытается вызвать

#0  0x04ae6000 in ??

вместо

#0  0x00000020 in ??

, когдаКодовый сегмент находится за пределами 0h (?) и ~ 15000h.

1 Ответ

1 голос
/ 05 октября 2011

Полагаю, вам нужно скопировать блок в run:after:repeat:, потому что тот, который вы передаете, основан на стеке и уничтожается при разматывании области действия.

...