如何确保代码不会被多次调用,但不会像 dispatch_once 那样在整个程序执行中阻塞它?

Posted

技术标签:

【中文标题】如何确保代码不会被多次调用,但不会像 dispatch_once 那样在整个程序执行中阻塞它?【英文标题】:How do I make sure code isn't called multiple times, but not block it for the whole program execution as with dispatch_once? 【发布时间】:2014-02-17 03:56:22 【问题描述】:

假设有一些东西我想确保在它已经执行时永远不会被调用。

UIScrollView 为例,每次发生任何缩放时都会调用scrollViewDidScroll: 方法。如果我想在第一次调用 [UIView animateWithDuration...] 时使用它,但不允许后续调用“覆盖”已经播放的动画怎么办?

dispatch_once 会完美运行,如果不是因为它只允许它在每次程序执行时运行一次,当我需要它运行多次时,而不是同时覆盖另一个。

我将如何阻止后续调用将事情搞砸?

【问题讨论】:

用一个标志来检查函数/块是否已经在运行怎么样? 基本一样的问题:Looping dispatch_after() in a method causes many simultaneous dispatches when method is rerun 【参考方案1】:

如果我理解,那么这样的事情应该可以工作(因为委托总是从主线程调用):

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
    static BOOL busy = NO;

    if (!busy) 
        busy = YES;

       [UIView animateWithDuration:0.2 animations:^
           // your animations
        completion:^(BOOL finished) 
           busy = NO;
       ];
    

此代码确保动画一次只能发生一个。

【讨论】:

如果动画在任何其他实例中运行,这将在每个实例中阻止 scrollViewDidScroll:。如果不是这样,您可以改用属性。 是的,好点。这段代码确实假设在任何时候应用程序中都只存在这个视图控制器的一个实例。使用 ivar 而不是 static 将是一个好主意。

以上是关于如何确保代码不会被多次调用,但不会像 dispatch_once 那样在整个程序执行中阻塞它?的主要内容,如果未能解决你的问题,请参考以下文章

当发布新图像时,确保图像不会在客户端浏览器中兑现的最佳方法是啥?

多次调用函数时 setState 不会发生变化

ios 8后台获取永远不会在设备上多次调用

如何确保一段代码永远不会离开 CPU 缓存(L3)?

不安全的 Rust 中的堆栈引用,但确保不安全不会从堆栈中泄漏?

如何确保图像不会水平或垂直拉伸[重复]