如何重复循环dispatch_after语句? [英] How do I repeatedly loop dispatch_after statements?

查看:234
本文介绍了如何重复循环dispatch_after语句?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在其中包含dispatch_after语句的for循环.问题是dispatch_after调用似乎与for循环不一致.换句话说,我希望它仅在dispatch_after块中的语句执行后才开始for循环的下一个迭代.

I want to have a for loop with dispatch_after statements in them. Problem is that the dispatch_after calls don't seem to go in line with the for loop. In other words, I want it to only start the next iteration of the for loop after the statements in the dispatch_after block have executed.

我该怎么做?

我想在屏幕上显示单词.传统上,我每秒显示一个字.但是,根据单词的长度,我现在想显示较长的单词,使显示的时间略长,而较短的单词显示的时间稍短.我想提出一个单词,稍等片刻(取决于单词的长度),然后提出下一个单词,稍等片刻,然后再下一个单词,等等.

I want to present words on screen. Traditionally I show one word per second. But depending on the word length, I now want to show longer words for slightly longer, and shorter words for slightly less time. I want to present a word, wait a little while (depending on how long the word is) then present the next word, wait a little while, then the next, etc.

推荐答案

这是实现此目的的一种方法.自然,您将需要用代码替换我的NSLog来显示单词,并用您要用来确定延迟的任何函数替换我简单的0.05 * word.length函数,但这应该可以解决问题,并且不会阻塞演示线程.

Here's one way to achieve this. Naturally, you will need to replace my NSLog with the code to show the word, and replace my simple 0.05 * word.length function with whatever function you're using to determine delay, but this should do the trick, and do it without blocking the presenting thread.

- (void)presentWord: (NSString*)word
{
    // Create a private, serial queue. This will preserve the ordering of the words
    static dispatch_queue_t wordQueue = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        wordQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
    });

    dispatch_async(wordQueue, ^{
        // Suspend the queue
        dispatch_suspend(wordQueue);

        // Show the word...
        NSLog(@"Now showing word: %@", word);

        // Calculate the delay until the next word should be shown...
        const NSTimeInterval timeToShow = 0.05 * word.length; // Or whatever your delay function is...

        // Have dispatch_after call us after that amount of time to resume the wordQueue.
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeToShow * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            dispatch_resume(wordQueue);
        });
    });
}

// There's nothing special here. Just split up a longer string into words, and pass them
// to presentWord: one at a time.
- (void)presentSentence: (NSString*)string
{
    NSArray* components = [string componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
    [components enumerateObjectsUsingBlock:^(NSString* obj, NSUInteger idx, BOOL *stop) {
        [self presentWord: obj];
    }];
}

这种方法的工作方式是我正在使用串行队列来维护单词的顺序.当您向-presentWords提交单词时,它将在wordQueue的背面"排队一个块.当该块开始执行时,您就知道wordQueue没有被挂起(因为您所在的块是在wordQueue上执行的块),而我们要做的第一件事就是挂起wordQueue.由于该块已经在运行中,因此它将运行到完成,但是直到有人恢复它之前,其他任何块都不会从wordQueue运行.挂起队列后,我们显示单词.它将一直显示,直到显示其他内容.然后,我们根据刚开始显示的单词的长度来计算延迟,并设置一个dispatch_after以在该时间过去之后恢复wordQueue.恢复串行队列后,下一个单词的块开始执行,挂起队列,整个过程重复进行.

The way this works is that I'm using a serial queue to maintain the ordering of the words. When you submit a word to -presentWords it enqueues a block at the "back" of wordQueue. When that block begins execution, you know that wordQueue is not suspended (because you're in a block that's executing on wordQueue) and the first thing we do is suspend wordQueue. Since this block is already "in flight" it will run to completion, but no other blocks will be run from wordQueue until someone resumes it. After suspending the queue, we display the word. It will remain displayed until something else is displayed. Then, we calculate the delay based on the length of the word we just started showing, and set up a dispatch_after to resume wordQueue after that time has passed. When the serial queue is resumed, the block for the next word begins executing, suspends the queue and the whole process repeats itself.

这篇关于如何重复循环dispatch_after语句?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆