调用定时器句柄时出现 BAD_ACCESS

发布于 2024-12-07 17:11:44 字数 1313 浏览 0 评论 0原文

我在 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];

但是当时间到了而没有输入 [Timer run] 时,它会出现 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(?) & 之外时 调用。 〜15000小时。

I have this realization of timer in 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

After that, I call it from my UIViewController.mm:

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

But it falls with EXC_BAD_ACCESS when time come w/o entering [Timer run]!

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

What am I doing wrong? Why it calls cs:20h? I have no such value (32) in my program at all!

After some minor changes timer tries to call

#0  0x04ae6000 in ??

instead of

#0  0x00000020 in ??

when the code seg is located beyond 0h(?) & ~15000h.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

_失温 2024-12-14 17:11:44

我的猜测是你需要 复制 run:after:repeat: 中的块,因为您传递的块是基于堆栈的并且当它所在的作用域展开时,它就会被销毁。

My guess is you need to copy the block in run:after:repeat: because the one you pass it is stack based and gets destroyed when the scope it is in unwinds.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文