如何确保某些代码每1秒运行次数不超过1次?

发布于 2024-12-04 10:23:05 字数 247 浏览 0 评论 0原文

我有一个程序可以从网上下载大量文件

我有几个线程下载数据。

调用每个数据后,我需要更新托管对象上下文。

如果 10 个线程大约同时完成加载,则托管对象上下文将运行 10 次。

事实上,我只需要运行一次。

我想做的是创建一个接受块的方法。

我应该做什么来创建一个接收块的函数,但如果该块在不到 1 秒前运行,则它不会运行该块,而是将第二次运行推迟到 1 秒,无论该函数运行的频率如何叫。

I have a program that download tons of files from the net

I have several threads downloading data.

After each data is called, I need to update the managed object contexts

If 10 threads finish loading at about the same time, then the managed object context will get run 10 times.

The truth is I only need to run it once.

What I want to do is to create a method that accept a block.

What should I do to make a function that receive a block, but if that block has been run less than 1 second ago, it won't run the block but instead would postpone the second running till 1 seconds no matter how often the function is called.

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

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

发布评论

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

评论(3

梦巷 2024-12-11 10:23:06

当线程完成时,调用主线程中的方法。在该方法中制作一个延迟 1 秒的计时器。

- (void)threadDidFinish
{
    if (_saveTimer != nil)
    {
        _saveTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(saveTimerDidFire) userInfo:nil repeats:NO];
    }
}

- (void)saveTimerDidFire
{
    [_saveTimer invalidate];
    _saveTimer = nil;

    // save the changes
}

这段代码将确保您每秒都可以保存,无论调用 threadDidFinish 次数如何。 NSTimer* _saveTimer 是一个实例变量。

When a thread finished call the method in the main thread. In that method make a timer with 1 second delay.

- (void)threadDidFinish
{
    if (_saveTimer != nil)
    {
        _saveTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(saveTimerDidFire) userInfo:nil repeats:NO];
    }
}

- (void)saveTimerDidFire
{
    [_saveTimer invalidate];
    _saveTimer = nil;

    // save the changes
}

This code will ensure you will save every second regardless of the number of times threadDidFinish was called. NSTimer* _saveTimer is an instance variable.

千寻… 2024-12-11 10:23:05

Mike Ash 已经实现了计时器类 为此。

您需要使用行为类型来初始化它,具体取决于您想要的具体行为:

  • MABGTimerDelay 表示每次调用 afterDelay:1.0 do:^{ /*code*/ } 它将把触发日期设置回来,以便它只在最后调用后运行一整秒。
  • MABGTimerCoalesce 意味着每次调用 afterDelay:1.0 do:^{ /*code*/ } 时,它都会将触发日期设置回原来的位置,这样它只会在一整秒后运行第一次调用。

如果它已经运行过,这两种行为都将允许您再次运行它,但只有在延迟再次过去之后才可以。

Mike Ash has already implemented a timer class for this.

You need to init it with a behaviour type, depending on the exact behaviour you want:

  • MABGTimerDelay means every time you call afterDelay:1.0 do:^{ /*code*/ } it will set the fire date back so that it only gets run a full second after the last call.
  • MABGTimerCoalesce means every time you call afterDelay:1.0 do:^{ /*code*/ } it will set the fire date back so that it only gets run a full second after the first call.

If it's already been run, both behaviours will allow you to run it again, but only after the delay has passed again.

近箐 2024-12-11 10:23:05

如果运行的块始终相同,则可以以一秒的间隔运行一个循环,检查布尔值,并且仅在布尔值为 YES 时才执行该块。像这样的事情:

    BOOL needsUpdate;
    -(void) loop {
    if (needsUpdate) {
        //Run Block
        needsUpdate = NO;
    }
    [self performSelector:@selector(loop) withObject:nil afterDelay:1.0];
    }

当线程完成加载时,您只需设置 needsUpdate = YES ,循环就会处理其余的事情。

If the block that gets run is always the same, you could have a loop running on a one second interval that checks a boolean value and only executes the block if the boolean value is YES. Something like this:

    BOOL needsUpdate;
    -(void) loop {
    if (needsUpdate) {
        //Run Block
        needsUpdate = NO;
    }
    [self performSelector:@selector(loop) withObject:nil afterDelay:1.0];
    }

When the threads finish loading, you just set needsUpdate = YES and the loop takes care of the rest.

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