dispatch_after循环/重复

Roe*_*aar 4 objective-c dispatch grand-central-dispatch ios

我想创建一个这样的循环:

while (TRUE){
  dispatch_after(...{
    <some action>
  });
}
Run Code Online (Sandbox Code Playgroud)

在viewDidLoad之后.我的想法是重复重复dispatch_after.dispatch_after在执行操作之前等待两秒钟.

这不起作用 - 屏幕只是空白?它是否陷入循环或......?

hfo*_*sli 12

是的,你可以用gcd做到这一点.但是你需要两个额外的c函数.

static void dispatch_async_repeated_internal(dispatch_time_t firstPopTime, double intervalInSeconds, dispatch_queue_t queue, void(^work)(BOOL *stop)) {    
    __block BOOL shouldStop = NO;
    dispatch_time_t nextPopTime = dispatch_time(firstPopTime, (int64_t)(intervalInSeconds * NSEC_PER_SEC));
    dispatch_after(nextPopTime, queue, ^{
        work(&shouldStop);
        if(!shouldStop) {
            dispatch_async_repeated_internal(nextPopTime, intervalInSeconds, queue, work);
        }
    });
}

void dispatch_async_repeated(double intervalInSeconds, dispatch_queue_t queue, void(^work)(BOOL *stop)) {
    dispatch_time_t firstPopTime = dispatch_time(DISPATCH_TIME_NOW, intervalInSeconds * NSEC_PER_SEC);
    dispatch_async_repeated_internal(firstPopTime, intervalInSeconds, queue, work);
}
Run Code Online (Sandbox Code Playgroud)

经测试!按预期工作.

https://gist.github.com/4676773


Dav*_*ist 6

dispatch_after(...)无论何时计划运行,呼叫都会立即返回.这意味着你的循环在调度它们之间不会等待两秒钟.相反,你正构建一个从现在起两秒钟内发生的无限队列,而不是彼此之间的两秒钟.

所以是的,你被困在一个无限循环中,即添加越来越多的块来执行.如果你想要每两秒钟发生一次事情,那么你可以使用重复的NSTimer或者在其内部使用块dispatch_after(以便第二个块在第一个块之后运行两秒钟).


hfo*_*sli 5

GCD已经内置了这个

dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
if (timer) {
    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, interval * NSEC_PER_SEC), interval * NSEC_PER_SEC, (1ull * NSEC_PER_SEC) / 10);
    dispatch_source_set_event_handler(timer, block);
    dispatch_resume(timer);
}
Run Code Online (Sandbox Code Playgroud)

https://gist.github.com/maicki/7622108