我遇到了GCD解决方案的问题。我有一个在后台运行的线程,它在给定的时间间隔内更新应用程序。为此,我使用计时器。
但是,如果用户想要更改此间隔,我会调用
dispatch_source_cancel(timer);
定义为
dispatch_source_set_cancel_handler(timer, ^{
dispatch_release(timer);
});
然后重启线程。当应用程序第二次更改间隔时,应用程序崩溃。即使我确实用新的间隔重新创建了计时器。
我可以避免释放计时器,但之后我会有记忆韭菜。
任何建议,该怎么办?
编辑: 定时器就像这样创建
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0, autoRefreshQueue);
if(!timer) {
return;
}
dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, refreshRate * NSEC_PER_SEC), refreshRate * NSEC_PER_SEC, refreshRate * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
//do work
});
答案 0 :(得分:1)
我认为这不是答案。 dispatch_source_cancel不会立即同步取消。
dispatch_source_cancel()函数异步取消调度源,防止进一步调用其事件处理程序块。取消不会中断当前正在执行的处理程序块(非抢先)。
因此,如果autoRefreshQueue是Global Queue,重新启动线程可能会同时调用这些块。
你是如何重新启动线程的?
<强>编辑:强>
然而,在引用或手册中没有提到为同一个Dispatch Source调用dispatch_source_set_timer两次(或更多),libdispatch / src / source.c中的dispatch_source_set_timer似乎没问题。至少,就我的测试而言,没有问题。
因此,只需调用dispatch_source_set_timer一个新的间隔。
dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, refreshRate * NSEC_PER_SEC), refreshRate * NSEC_PER_SEC, refreshRate * NSEC_PER_SEC);