52

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

performSelector:withObject:afterDelay:

或使用NSTimer.

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

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

    }completion:^(BOOL finished){
}];

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

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

4

4 回答 4

140

使用 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];
});
于 2013-03-14T15:13:09.147 回答
24

扩展已接受的答案,我为那些不想在每次想要执行此操作时记住语法的人创建了一个 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();
           }
      });
}
于 2014-03-28T00:47:00.937 回答
3

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

  1. 单击+Xcode 右上角的按钮。
  2. 搜索after
  3. 它将仅返回 1 个搜索结果,即所需的片段(见屏幕截图)。双击它,你就可以开始了。

说明如何从 Xcode 本身中获取代码段的屏幕截图

于 2020-06-18T13:20:24.903 回答
2

以下是在 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

于 2015-12-01T22:30:08.860 回答