带有块的 Objective-C 延迟动作

Posted

技术标签:

【中文标题】带有块的 Objective-C 延迟动作【英文标题】:Objective-C delay action with blocks 【发布时间】:2013-03-14 15:10:50 【问题描述】:

我知道在 Objective-C 中有几种延迟动作的方法,例如:

performSelector:withObject:afterDelay:

或使用NSTimer

但是有一种奇特的东西叫做块,你可以在其中做这样的事情:

[UIView animateWithDuration:1.50 delay:0 options:(UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionBeginFromCurrentState) animations:^

    completion:^(BOOL finished)
];

不幸的是,这种方法只适用于动画。

如何在一个方法中使用块创建延迟,这样我就不必使用所有这些 @selectors 并且无需创建 新的单独方法强>?谢谢!

【问题讨论】:

这对您有帮助吗? ***.com/questions/15218861/… 你为什么害怕创建一个单独的方法?这将立即解决问题。 @ShivanRaptor 因为我已经有很多方法了,我想找到更好的方法 我不确定它是否会起作用,但您可以尝试在完成中调用方法:^(BOOL finished) 块 啊,我的问题是我看错了你的代码示例。 :) 你以非常奇怪的顺序发现了一些东西,但这是一个很好的问题。感谢您发布它。 【参考方案1】:

使用 dispatch_after:

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
    //code to be executed on the main queue after delay
    [self doSometingWithObject:obj1 andAnotherObject:obj2];
);

【讨论】:

它大大提高了可读性——尤其是当您使用块作为方法参数时 在函数/方法中隐藏这个(尤其是popTime计算)会很好,例如[NSObject performBlock:afterDelay:];【参考方案2】:

在已接受的答案的基础上,我为那些不想每次都记住语法的人创建了一个 Helper 函数:) 我只是有一个 Utils 类:

用法:

[Utils delayCallback:^
     //--- code here
 forTotalSeconds:0.3];

辅助方法:

+ (void) delayCallback: (void(^)(void))callback forTotalSeconds: (double)delayInSeconds

     dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
     dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
           if(callback)
                callback();
           
      );

【讨论】:

【参考方案3】:

Xcode 11.3.1(至少,以及其他版本的 Xcode)提供了一个代码 sn-p 来执行此操作,您只需输入延迟值和您希望在延迟后运行的代码。

    点击Xcode右上角的+按钮。 搜索after 它将只返回 1 个搜索结果,即所需的 sn-p(见屏幕截图)。双击它,你就可以开始了。

【讨论】:

哇!你发现隐藏在 XCode 中的疯狂东西!【参考方案4】:

以下是在 Swift 中延迟后触发块的方法:

runThisAfterDelay(seconds: 4)  () -> () in
    print("Prints this 4 seconds later in main queue")
    // Or just call animatedMyObject() right here


/// EZSwiftExtensions
func runThisAfterDelay(seconds seconds: Double, after: () -> ()) 
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))
    dispatch_after(time, dispatch_get_main_queue(), after)

它作为标准功能包含在我的仓库中: https://github.com/goktugyil/EZSwiftExtensions

【讨论】:

语言错误。问题是关于 Obj-C

以上是关于带有块的 Objective-C 延迟动作的主要内容,如果未能解决你的问题,请参考以下文章

执行块的最长时间............带有重试和中间延迟

带有块的 UIView 动画如何在幕后工作

Angular 6 - 指定延迟加载块的路径

完成块 Objective-C

IOS/Objective-C:调用完成块的语法

将objective-c面向块的api转换为android