调用定时器句柄时出现 BAD_ACCESS
我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我的猜测是你需要 复制
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.